/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/**
 * Autogenerated by Thrift Compiler (0.10.0)
 *
 * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
 *  @generated
 */
package org.apache.accumulo.proxy.thrift;

@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.10.0)")
public class AccumuloProxy {

  public interface Iface {

    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(java.nio.ByteBuffer login, java.lang.String tableName, java.lang.String constraintClassName) 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(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(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(java.nio.ByteBuffer login, java.lang.String tableName) throws TableNotFoundException, 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(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(java.nio.ByteBuffer login, java.lang.String tableName) throws AccumuloSecurityException, TableNotFoundException, AccumuloException, 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(java.nio.ByteBuffer login, java.lang.String tableName) 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(java.nio.ByteBuffer login, java.lang.String tableName, java.lang.String exportDir) 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 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 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(java.nio.ByteBuffer login, java.lang.String tableName, java.lang.String iteratorName, IteratorScope scope) 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 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(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(java.nio.ByteBuffer login, java.lang.String tableName, java.lang.String importDir) throws TableExistsException, AccumuloException, AccumuloSecurityException, 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 java.util.Set<java.lang.String> listTables(java.nio.ByteBuffer login) throws 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 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(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(java.nio.ByteBuffer login, java.lang.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(java.nio.ByteBuffer login, java.lang.String tableName, int constraint) 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(java.nio.ByteBuffer login, java.lang.String tableName, java.lang.String property) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, 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(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(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 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(java.nio.ByteBuffer login, java.lang.String tableName) 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(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(java.nio.ByteBuffer login, java.lang.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 java.util.List<ActiveCompaction> getActiveCompactions(java.nio.ByteBuffer login, java.lang.String tserver) 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 java.util.Map<java.lang.String,java.lang.String> getSystemConfiguration(java.nio.ByteBuffer login) throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException;

    public java.util.List<java.lang.String> getTabletServers(java.nio.ByteBuffer login) throws 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(java.nio.ByteBuffer login, java.lang.String property, java.lang.String value) 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(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(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(java.nio.ByteBuffer login, java.lang.String user, java.nio.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(java.nio.ByteBuffer login, java.lang.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(java.nio.ByteBuffer login, java.lang.String user, SystemPermission perm) throws AccumuloException, AccumuloSecurityException, 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(java.nio.ByteBuffer login, java.lang.String user, SystemPermission perm) throws AccumuloException, AccumuloSecurityException, 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 java.util.Set<java.lang.String> listLocalUsers(java.nio.ByteBuffer login) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, 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(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(java.nio.ByteBuffer login, java.lang.String user, java.lang.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(java.nio.ByteBuffer login, java.lang.String user, java.lang.String namespaceName, NamespacePermission perm) throws AccumuloException, AccumuloSecurityException, 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 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(java.lang.String scanner) throws UnknownScanner, org.apache.thrift.TException;

    public KeyValueAndPeek nextEntry(java.lang.String scanner) 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(java.lang.String scanner) throws UnknownScanner, 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 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(java.lang.String writer, java.util.Map<java.nio.ByteBuffer,java.util.List<ColumnUpdate>> cells) throws org.apache.thrift.TException;

    public void flush(java.lang.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(java.nio.ByteBuffer login, java.lang.String tableName, java.nio.ByteBuffer row, ConditionalUpdates updates) 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 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(java.lang.String conditionalWriter) 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 java.lang.String systemNamespace() throws org.apache.thrift.TException;

    public java.lang.String defaultNamespace() throws 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(java.nio.ByteBuffer login, java.lang.String namespaceName) throws AccumuloException, AccumuloSecurityException, 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(java.nio.ByteBuffer login, java.lang.String namespaceName) throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, NamespaceNotEmptyException, 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(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(java.nio.ByteBuffer login, java.lang.String namespaceName, java.lang.String property) 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 java.util.Map<java.lang.String,java.lang.String> namespaceIdMap(java.nio.ByteBuffer login) throws AccumuloException, AccumuloSecurityException, 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(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(java.nio.ByteBuffer login, java.lang.String namespaceName, java.lang.String name, IteratorScope scope) 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(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(java.nio.ByteBuffer login, java.lang.String namespaceName, java.lang.String constraintClassName) 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 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(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(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(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(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(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(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(java.nio.ByteBuffer login, java.lang.String tableName, org.apache.thrift.async.AsyncMethodCallback<Void> 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(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(java.nio.ByteBuffer login, java.lang.String tableName, org.apache.thrift.async.AsyncMethodCallback<Void> 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(java.nio.ByteBuffer login, java.lang.String tableName, org.apache.thrift.async.AsyncMethodCallback<Void> 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(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(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(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(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(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(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(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(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(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(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(java.nio.ByteBuffer login, org.apache.thrift.async.AsyncMethodCallback<java.util.Set<java.lang.String>> 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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(java.nio.ByteBuffer login, java.lang.String tserver, org.apache.thrift.async.AsyncMethodCallback<Void> 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(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(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(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(java.nio.ByteBuffer login, org.apache.thrift.async.AsyncMethodCallback<java.util.List<java.lang.String>> 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(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(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(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(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(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(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(java.nio.ByteBuffer login, java.lang.String user, org.apache.thrift.async.AsyncMethodCallback<Void> 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(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(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(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(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(java.nio.ByteBuffer login, org.apache.thrift.async.AsyncMethodCallback<java.util.Set<java.lang.String>> 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(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(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(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(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(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(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(java.lang.String scanner, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> 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(java.lang.String scanner, int k, org.apache.thrift.async.AsyncMethodCallback<ScanResult> 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(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(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(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(java.lang.String writer, org.apache.thrift.async.AsyncMethodCallback<Void> 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(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(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(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(java.lang.String conditionalWriter, org.apache.thrift.async.AsyncMethodCallback<Void> 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<Key> 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<java.lang.String> 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(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(java.nio.ByteBuffer login, java.lang.String namespaceName, org.apache.thrift.async.AsyncMethodCallback<Void> 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(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(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(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(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(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(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(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(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(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(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(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(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(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(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.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) {
        return new Client(prot);
      }
      public Client getClient(org.apache.thrift.protocol.TProtocol iprot, org.apache.thrift.protocol.TProtocol oprot) {
        return new Client(iprot, oprot);
      }
    }

    public Client(org.apache.thrift.protocol.TProtocol prot)
    {
      super(prot, prot);
    }

    public Client(org.apache.thrift.protocol.TProtocol iprot, org.apache.thrift.protocol.TProtocol oprot) {
      super(iprot, oprot);
    }

    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(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);
      args.setLoginProperties(loginProperties);
      sendBase("login", args);
    }

    public java.nio.ByteBuffer recv_login() throws AccumuloSecurityException, org.apache.thrift.TException
    {
      login_result result = new login_result();
      receiveBase(result, "login");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ouch2 != null) {
        throw result.ouch2;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "login failed: unknown result");
    }

    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(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);
      args.setTableName(tableName);
      args.setConstraintClassName(constraintClassName);
      sendBase("addConstraint", args);
    }

    public int recv_addConstraint() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
    {
      addConstraint_result result = new addConstraint_result();
      receiveBase(result, "addConstraint");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ouch1 != null) {
        throw result.ouch1;
      }
      if (result.ouch2 != null) {
        throw result.ouch2;
      }
      if (result.ouch3 != null) {
        throw result.ouch3;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "addConstraint failed: unknown result");
    }

    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(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);
      args.setTableName(tableName);
      args.setSplits(splits);
      sendBase("addSplits", args);
    }

    public void recv_addSplits() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
    {
      addSplits_result result = new addSplits_result();
      receiveBase(result, "addSplits");
      if (result.ouch1 != null) {
        throw result.ouch1;
      }
      if (result.ouch2 != null) {
        throw result.ouch2;
      }
      if (result.ouch3 != null) {
        throw result.ouch3;
      }
      return;
    }

    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(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);
      args.setTableName(tableName);
      args.setSetting(setting);
      args.setScopes(scopes);
      sendBase("attachIterator", args);
    }

    public void recv_attachIterator() throws AccumuloSecurityException, AccumuloException, TableNotFoundException, org.apache.thrift.TException
    {
      attachIterator_result result = new attachIterator_result();
      receiveBase(result, "attachIterator");
      if (result.ouch1 != null) {
        throw result.ouch1;
      }
      if (result.ouch2 != null) {
        throw result.ouch2;
      }
      if (result.ouch3 != null) {
        throw result.ouch3;
      }
      return;
    }

    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(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);
      args.setTableName(tableName);
      args.setSetting(setting);
      args.setScopes(scopes);
      sendBase("checkIteratorConflicts", args);
    }

    public void recv_checkIteratorConflicts() throws AccumuloSecurityException, AccumuloException, TableNotFoundException, org.apache.thrift.TException
    {
      checkIteratorConflicts_result result = new checkIteratorConflicts_result();
      receiveBase(result, "checkIteratorConflicts");
      if (result.ouch1 != null) {
        throw result.ouch1;
      }
      if (result.ouch2 != null) {
        throw result.ouch2;
      }
      if (result.ouch3 != null) {
        throw result.ouch3;
      }
      return;
    }

    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(java.nio.ByteBuffer login, java.lang.String tableName) throws org.apache.thrift.TException
    {
      clearLocatorCache_args args = new clearLocatorCache_args();
      args.setLogin(login);
      args.setTableName(tableName);
      sendBase("clearLocatorCache", args);
    }

    public void recv_clearLocatorCache() throws TableNotFoundException, org.apache.thrift.TException
    {
      clearLocatorCache_result result = new clearLocatorCache_result();
      receiveBase(result, "clearLocatorCache");
      if (result.ouch1 != null) {
        throw result.ouch1;
      }
      return;
    }

    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(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);
      args.setTableName(tableName);
      args.setNewTableName(newTableName);
      args.setFlush(flush);
      args.setPropertiesToSet(propertiesToSet);
      args.setPropertiesToExclude(propertiesToExclude);
      sendBase("cloneTable", args);
    }

    public void recv_cloneTable() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, TableExistsException, org.apache.thrift.TException
    {
      cloneTable_result result = new cloneTable_result();
      receiveBase(result, "cloneTable");
      if (result.ouch1 != null) {
        throw result.ouch1;
      }
      if (result.ouch2 != null) {
        throw result.ouch2;
      }
      if (result.ouch3 != null) {
        throw result.ouch3;
      }
      if (result.ouch4 != null) {
        throw result.ouch4;
      }
      return;
    }

    public void 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(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);
      args.setTableName(tableName);
      args.setStartRow(startRow);
      args.setEndRow(endRow);
      args.setIterators(iterators);
      args.setFlush(flush);
      args.setWait(wait);
      args.setCompactionStrategy(compactionStrategy);
      sendBase("compactTable", args);
    }

    public void recv_compactTable() throws AccumuloSecurityException, TableNotFoundException, AccumuloException, org.apache.thrift.TException
    {
      compactTable_result result = new compactTable_result();
      receiveBase(result, "compactTable");
      if (result.ouch1 != null) {
        throw result.ouch1;
      }
      if (result.ouch2 != null) {
        throw result.ouch2;
      }
      if (result.ouch3 != null) {
        throw result.ouch3;
      }
      return;
    }

    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(java.nio.ByteBuffer login, java.lang.String tableName) throws org.apache.thrift.TException
    {
      cancelCompaction_args args = new cancelCompaction_args();
      args.setLogin(login);
      args.setTableName(tableName);
      sendBase("cancelCompaction", args);
    }

    public void recv_cancelCompaction() throws AccumuloSecurityException, TableNotFoundException, AccumuloException, org.apache.thrift.TException
    {
      cancelCompaction_result result = new cancelCompaction_result();
      receiveBase(result, "cancelCompaction");
      if (result.ouch1 != null) {
        throw result.ouch1;
      }
      if (result.ouch2 != null) {
        throw result.ouch2;
      }
      if (result.ouch3 != null) {
        throw result.ouch3;
      }
      return;
    }

    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(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);
      args.setTableName(tableName);
      args.setVersioningIter(versioningIter);
      args.setType(type);
      sendBase("createTable", args);
    }

    public void recv_createTable() throws AccumuloException, AccumuloSecurityException, TableExistsException, org.apache.thrift.TException
    {
      createTable_result result = new createTable_result();
      receiveBase(result, "createTable");
      if (result.ouch1 != null) {
        throw result.ouch1;
      }
      if (result.ouch2 != null) {
        throw result.ouch2;
      }
      if (result.ouch3 != null) {
        throw result.ouch3;
      }
      return;
    }

    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(java.nio.ByteBuffer login, java.lang.String tableName) throws org.apache.thrift.TException
    {
      deleteTable_args args = new deleteTable_args();
      args.setLogin(login);
      args.setTableName(tableName);
      sendBase("deleteTable", args);
    }

    public void recv_deleteTable() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
    {
      deleteTable_result result = new deleteTable_result();
      receiveBase(result, "deleteTable");
      if (result.ouch1 != null) {
        throw result.ouch1;
      }
      if (result.ouch2 != null) {
        throw result.ouch2;
      }
      if (result.ouch3 != null) {
        throw result.ouch3;
      }
      return;
    }

    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(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);
      args.setTableName(tableName);
      args.setStartRow(startRow);
      args.setEndRow(endRow);
      sendBase("deleteRows", args);
    }

    public void recv_deleteRows() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
    {
      deleteRows_result result = new deleteRows_result();
      receiveBase(result, "deleteRows");
      if (result.ouch1 != null) {
        throw result.ouch1;
      }
      if (result.ouch2 != null) {
        throw result.ouch2;
      }
      if (result.ouch3 != null) {
        throw result.ouch3;
      }
      return;
    }

    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(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);
      args.setTableName(tableName);
      args.setExportDir(exportDir);
      sendBase("exportTable", args);
    }

    public void recv_exportTable() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
    {
      exportTable_result result = new exportTable_result();
      receiveBase(result, "exportTable");
      if (result.ouch1 != null) {
        throw result.ouch1;
      }
      if (result.ouch2 != null) {
        throw result.ouch2;
      }
      if (result.ouch3 != null) {
        throw result.ouch3;
      }
      return;
    }

    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(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);
      args.setTableName(tableName);
      args.setStartRow(startRow);
      args.setEndRow(endRow);
      args.setWait(wait);
      sendBase("flushTable", args);
    }

    public void recv_flushTable() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
    {
      flushTable_result result = new flushTable_result();
      receiveBase(result, "flushTable");
      if (result.ouch1 != null) {
        throw result.ouch1;
      }
      if (result.ouch2 != null) {
        throw result.ouch2;
      }
      if (result.ouch3 != null) {
        throw result.ouch3;
      }
      return;
    }

    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(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);
      args.setTables(tables);
      sendBase("getDiskUsage", args);
    }

    public java.util.List<DiskUsage> recv_getDiskUsage() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
    {
      getDiskUsage_result result = new getDiskUsage_result();
      receiveBase(result, "getDiskUsage");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ouch1 != null) {
        throw result.ouch1;
      }
      if (result.ouch2 != null) {
        throw result.ouch2;
      }
      if (result.ouch3 != null) {
        throw result.ouch3;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getDiskUsage failed: unknown result");
    }

    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(java.nio.ByteBuffer login, java.lang.String tableName) throws org.apache.thrift.TException
    {
      getLocalityGroups_args args = new getLocalityGroups_args();
      args.setLogin(login);
      args.setTableName(tableName);
      sendBase("getLocalityGroups", args);
    }

    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");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ouch1 != null) {
        throw result.ouch1;
      }
      if (result.ouch2 != null) {
        throw result.ouch2;
      }
      if (result.ouch3 != null) {
        throw result.ouch3;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getLocalityGroups failed: unknown result");
    }

    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(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);
      args.setTableName(tableName);
      args.setIteratorName(iteratorName);
      args.setScope(scope);
      sendBase("getIteratorSetting", args);
    }

    public IteratorSetting recv_getIteratorSetting() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
    {
      getIteratorSetting_result result = new getIteratorSetting_result();
      receiveBase(result, "getIteratorSetting");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ouch1 != null) {
        throw result.ouch1;
      }
      if (result.ouch2 != null) {
        throw result.ouch2;
      }
      if (result.ouch3 != null) {
        throw result.ouch3;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getIteratorSetting failed: unknown result");
    }

    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(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);
      args.setTableName(tableName);
      args.setAuths(auths);
      args.setStartRow(startRow);
      args.setStartInclusive(startInclusive);
      args.setEndRow(endRow);
      args.setEndInclusive(endInclusive);
      sendBase("getMaxRow", args);
    }

    public java.nio.ByteBuffer recv_getMaxRow() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
    {
      getMaxRow_result result = new getMaxRow_result();
      receiveBase(result, "getMaxRow");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ouch1 != null) {
        throw result.ouch1;
      }
      if (result.ouch2 != null) {
        throw result.ouch2;
      }
      if (result.ouch3 != null) {
        throw result.ouch3;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getMaxRow failed: unknown result");
    }

    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(java.nio.ByteBuffer login, java.lang.String tableName) throws org.apache.thrift.TException
    {
      getTableProperties_args args = new getTableProperties_args();
      args.setLogin(login);
      args.setTableName(tableName);
      sendBase("getTableProperties", args);
    }

    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");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ouch1 != null) {
        throw result.ouch1;
      }
      if (result.ouch2 != null) {
        throw result.ouch2;
      }
      if (result.ouch3 != null) {
        throw result.ouch3;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getTableProperties failed: unknown result");
    }

    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(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);
      args.setTableName(tableName);
      args.setImportDir(importDir);
      args.setFailureDir(failureDir);
      args.setSetTime(setTime);
      sendBase("importDirectory", args);
    }

    public void recv_importDirectory() throws TableNotFoundException, AccumuloException, AccumuloSecurityException, org.apache.thrift.TException
    {
      importDirectory_result result = new importDirectory_result();
      receiveBase(result, "importDirectory");
      if (result.ouch1 != null) {
        throw result.ouch1;
      }
      if (result.ouch3 != null) {
        throw result.ouch3;
      }
      if (result.ouch4 != null) {
        throw result.ouch4;
      }
      return;
    }

    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(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);
      args.setTableName(tableName);
      args.setImportDir(importDir);
      sendBase("importTable", args);
    }

    public void recv_importTable() throws TableExistsException, AccumuloException, AccumuloSecurityException, org.apache.thrift.TException
    {
      importTable_result result = new importTable_result();
      receiveBase(result, "importTable");
      if (result.ouch1 != null) {
        throw result.ouch1;
      }
      if (result.ouch2 != null) {
        throw result.ouch2;
      }
      if (result.ouch3 != null) {
        throw result.ouch3;
      }
      return;
    }

    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(java.nio.ByteBuffer login, java.lang.String tableName, int maxSplits) throws org.apache.thrift.TException
    {
      listSplits_args args = new listSplits_args();
      args.setLogin(login);
      args.setTableName(tableName);
      args.setMaxSplits(maxSplits);
      sendBase("listSplits", args);
    }

    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");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ouch1 != null) {
        throw result.ouch1;
      }
      if (result.ouch2 != null) {
        throw result.ouch2;
      }
      if (result.ouch3 != null) {
        throw result.ouch3;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "listSplits failed: unknown result");
    }

    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(java.nio.ByteBuffer login) throws org.apache.thrift.TException
    {
      listTables_args args = new listTables_args();
      args.setLogin(login);
      sendBase("listTables", args);
    }

    public java.util.Set<java.lang.String> recv_listTables() throws org.apache.thrift.TException
    {
      listTables_result result = new listTables_result();
      receiveBase(result, "listTables");
      if (result.isSetSuccess()) {
        return result.success;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "listTables failed: unknown result");
    }

    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(java.nio.ByteBuffer login, java.lang.String tableName) throws org.apache.thrift.TException
    {
      listIterators_args args = new listIterators_args();
      args.setLogin(login);
      args.setTableName(tableName);
      sendBase("listIterators", args);
    }

    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");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ouch1 != null) {
        throw result.ouch1;
      }
      if (result.ouch2 != null) {
        throw result.ouch2;
      }
      if (result.ouch3 != null) {
        throw result.ouch3;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "listIterators failed: unknown result");
    }

    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(java.nio.ByteBuffer login, java.lang.String tableName) throws org.apache.thrift.TException
    {
      listConstraints_args args = new listConstraints_args();
      args.setLogin(login);
      args.setTableName(tableName);
      sendBase("listConstraints", args);
    }

    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");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ouch1 != null) {
        throw result.ouch1;
      }
      if (result.ouch2 != null) {
        throw result.ouch2;
      }
      if (result.ouch3 != null) {
        throw result.ouch3;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "listConstraints failed: unknown result");
    }

    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(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);
      args.setTableName(tableName);
      args.setStartRow(startRow);
      args.setEndRow(endRow);
      sendBase("mergeTablets", args);
    }

    public void recv_mergeTablets() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
    {
      mergeTablets_result result = new mergeTablets_result();
      receiveBase(result, "mergeTablets");
      if (result.ouch1 != null) {
        throw result.ouch1;
      }
      if (result.ouch2 != null) {
        throw result.ouch2;
      }
      if (result.ouch3 != null) {
        throw result.ouch3;
      }
      return;
    }

    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(java.nio.ByteBuffer login, java.lang.String tableName, boolean wait) throws org.apache.thrift.TException
    {
      offlineTable_args args = new offlineTable_args();
      args.setLogin(login);
      args.setTableName(tableName);
      args.setWait(wait);
      sendBase("offlineTable", args);
    }

    public void recv_offlineTable() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
    {
      offlineTable_result result = new offlineTable_result();
      receiveBase(result, "offlineTable");
      if (result.ouch1 != null) {
        throw result.ouch1;
      }
      if (result.ouch2 != null) {
        throw result.ouch2;
      }
      if (result.ouch3 != null) {
        throw result.ouch3;
      }
      return;
    }

    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(java.nio.ByteBuffer login, java.lang.String tableName, boolean wait) throws org.apache.thrift.TException
    {
      onlineTable_args args = new onlineTable_args();
      args.setLogin(login);
      args.setTableName(tableName);
      args.setWait(wait);
      sendBase("onlineTable", args);
    }

    public void recv_onlineTable() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
    {
      onlineTable_result result = new onlineTable_result();
      receiveBase(result, "onlineTable");
      if (result.ouch1 != null) {
        throw result.ouch1;
      }
      if (result.ouch2 != null) {
        throw result.ouch2;
      }
      if (result.ouch3 != null) {
        throw result.ouch3;
      }
      return;
    }

    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(java.nio.ByteBuffer login, java.lang.String tableName, int constraint) throws org.apache.thrift.TException
    {
      removeConstraint_args args = new removeConstraint_args();
      args.setLogin(login);
      args.setTableName(tableName);
      args.setConstraint(constraint);
      sendBase("removeConstraint", args);
    }

    public void recv_removeConstraint() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
    {
      removeConstraint_result result = new removeConstraint_result();
      receiveBase(result, "removeConstraint");
      if (result.ouch1 != null) {
        throw result.ouch1;
      }
      if (result.ouch2 != null) {
        throw result.ouch2;
      }
      if (result.ouch3 != null) {
        throw result.ouch3;
      }
      return;
    }

    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(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);
      args.setTableName(tableName);
      args.setIterName(iterName);
      args.setScopes(scopes);
      sendBase("removeIterator", args);
    }

    public void recv_removeIterator() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
    {
      removeIterator_result result = new removeIterator_result();
      receiveBase(result, "removeIterator");
      if (result.ouch1 != null) {
        throw result.ouch1;
      }
      if (result.ouch2 != null) {
        throw result.ouch2;
      }
      if (result.ouch3 != null) {
        throw result.ouch3;
      }
      return;
    }

    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(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);
      args.setTableName(tableName);
      args.setProperty(property);
      sendBase("removeTableProperty", args);
    }

    public void recv_removeTableProperty() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
    {
      removeTableProperty_result result = new removeTableProperty_result();
      receiveBase(result, "removeTableProperty");
      if (result.ouch1 != null) {
        throw result.ouch1;
      }
      if (result.ouch2 != null) {
        throw result.ouch2;
      }
      if (result.ouch3 != null) {
        throw result.ouch3;
      }
      return;
    }

    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(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);
      args.setOldTableName(oldTableName);
      args.setNewTableName(newTableName);
      sendBase("renameTable", args);
    }

    public void recv_renameTable() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, TableExistsException, org.apache.thrift.TException
    {
      renameTable_result result = new renameTable_result();
      receiveBase(result, "renameTable");
      if (result.ouch1 != null) {
        throw result.ouch1;
      }
      if (result.ouch2 != null) {
        throw result.ouch2;
      }
      if (result.ouch3 != null) {
        throw result.ouch3;
      }
      if (result.ouch4 != null) {
        throw result.ouch4;
      }
      return;
    }

    public void 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(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);
      args.setTableName(tableName);
      args.setGroups(groups);
      sendBase("setLocalityGroups", args);
    }

    public void recv_setLocalityGroups() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
    {
      setLocalityGroups_result result = new setLocalityGroups_result();
      receiveBase(result, "setLocalityGroups");
      if (result.ouch1 != null) {
        throw result.ouch1;
      }
      if (result.ouch2 != null) {
        throw result.ouch2;
      }
      if (result.ouch3 != null) {
        throw result.ouch3;
      }
      return;
    }

    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(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);
      args.setTableName(tableName);
      args.setProperty(property);
      args.setValue(value);
      sendBase("setTableProperty", args);
    }

    public void recv_setTableProperty() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
    {
      setTableProperty_result result = new setTableProperty_result();
      receiveBase(result, "setTableProperty");
      if (result.ouch1 != null) {
        throw result.ouch1;
      }
      if (result.ouch2 != null) {
        throw result.ouch2;
      }
      if (result.ouch3 != null) {
        throw result.ouch3;
      }
      return;
    }

    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(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);
      args.setTableName(tableName);
      args.setRange(range);
      args.setMaxSplits(maxSplits);
      sendBase("splitRangeByTablets", args);
    }

    public java.util.Set<Range> recv_splitRangeByTablets() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
    {
      splitRangeByTablets_result result = new splitRangeByTablets_result();
      receiveBase(result, "splitRangeByTablets");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ouch1 != null) {
        throw result.ouch1;
      }
      if (result.ouch2 != null) {
        throw result.ouch2;
      }
      if (result.ouch3 != null) {
        throw result.ouch3;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "splitRangeByTablets failed: unknown result");
    }

    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(java.nio.ByteBuffer login, java.lang.String tableName) throws org.apache.thrift.TException
    {
      tableExists_args args = new tableExists_args();
      args.setLogin(login);
      args.setTableName(tableName);
      sendBase("tableExists", args);
    }

    public boolean recv_tableExists() throws org.apache.thrift.TException
    {
      tableExists_result result = new tableExists_result();
      receiveBase(result, "tableExists");
      if (result.isSetSuccess()) {
        return result.success;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "tableExists failed: unknown result");
    }

    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(java.nio.ByteBuffer login) throws org.apache.thrift.TException
    {
      tableIdMap_args args = new tableIdMap_args();
      args.setLogin(login);
      sendBase("tableIdMap", args);
    }

    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");
      if (result.isSetSuccess()) {
        return result.success;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "tableIdMap failed: unknown result");
    }

    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(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);
      args.setTableName(tableName);
      args.setClassName(className);
      args.setAsTypeName(asTypeName);
      sendBase("testTableClassLoad", args);
    }

    public boolean recv_testTableClassLoad() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
    {
      testTableClassLoad_result result = new testTableClassLoad_result();
      receiveBase(result, "testTableClassLoad");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ouch1 != null) {
        throw result.ouch1;
      }
      if (result.ouch2 != null) {
        throw result.ouch2;
      }
      if (result.ouch3 != null) {
        throw result.ouch3;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "testTableClassLoad failed: unknown result");
    }

    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(java.nio.ByteBuffer login, java.lang.String tserver) throws org.apache.thrift.TException
    {
      pingTabletServer_args args = new pingTabletServer_args();
      args.setLogin(login);
      args.setTserver(tserver);
      sendBase("pingTabletServer", args);
    }

    public void recv_pingTabletServer() throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException
    {
      pingTabletServer_result result = new pingTabletServer_result();
      receiveBase(result, "pingTabletServer");
      if (result.ouch1 != null) {
        throw result.ouch1;
      }
      if (result.ouch2 != null) {
        throw result.ouch2;
      }
      return;
    }

    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(java.nio.ByteBuffer login, java.lang.String tserver) throws org.apache.thrift.TException
    {
      getActiveScans_args args = new getActiveScans_args();
      args.setLogin(login);
      args.setTserver(tserver);
      sendBase("getActiveScans", args);
    }

    public java.util.List<ActiveScan> recv_getActiveScans() throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException
    {
      getActiveScans_result result = new getActiveScans_result();
      receiveBase(result, "getActiveScans");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ouch1 != null) {
        throw result.ouch1;
      }
      if (result.ouch2 != null) {
        throw result.ouch2;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getActiveScans failed: unknown result");
    }

    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(java.nio.ByteBuffer login, java.lang.String tserver) throws org.apache.thrift.TException
    {
      getActiveCompactions_args args = new getActiveCompactions_args();
      args.setLogin(login);
      args.setTserver(tserver);
      sendBase("getActiveCompactions", args);
    }

    public java.util.List<ActiveCompaction> recv_getActiveCompactions() throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException
    {
      getActiveCompactions_result result = new getActiveCompactions_result();
      receiveBase(result, "getActiveCompactions");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ouch1 != null) {
        throw result.ouch1;
      }
      if (result.ouch2 != null) {
        throw result.ouch2;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getActiveCompactions failed: unknown result");
    }

    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(java.nio.ByteBuffer login) throws org.apache.thrift.TException
    {
      getSiteConfiguration_args args = new getSiteConfiguration_args();
      args.setLogin(login);
      sendBase("getSiteConfiguration", args);
    }

    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");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ouch1 != null) {
        throw result.ouch1;
      }
      if (result.ouch2 != null) {
        throw result.ouch2;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getSiteConfiguration failed: unknown result");
    }

    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(java.nio.ByteBuffer login) throws org.apache.thrift.TException
    {
      getSystemConfiguration_args args = new getSystemConfiguration_args();
      args.setLogin(login);
      sendBase("getSystemConfiguration", args);
    }

    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");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ouch1 != null) {
        throw result.ouch1;
      }
      if (result.ouch2 != null) {
        throw result.ouch2;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getSystemConfiguration failed: unknown result");
    }

    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(java.nio.ByteBuffer login) throws org.apache.thrift.TException
    {
      getTabletServers_args args = new getTabletServers_args();
      args.setLogin(login);
      sendBase("getTabletServers", args);
    }

    public java.util.List<java.lang.String> recv_getTabletServers() throws org.apache.thrift.TException
    {
      getTabletServers_result result = new getTabletServers_result();
      receiveBase(result, "getTabletServers");
      if (result.isSetSuccess()) {
        return result.success;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getTabletServers failed: unknown result");
    }

    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(java.nio.ByteBuffer login, java.lang.String property) throws org.apache.thrift.TException
    {
      removeProperty_args args = new removeProperty_args();
      args.setLogin(login);
      args.setProperty(property);
      sendBase("removeProperty", args);
    }

    public void recv_removeProperty() throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException
    {
      removeProperty_result result = new removeProperty_result();
      receiveBase(result, "removeProperty");
      if (result.ouch1 != null) {
        throw result.ouch1;
      }
      if (result.ouch2 != null) {
        throw result.ouch2;
      }
      return;
    }

    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(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);
      args.setProperty(property);
      args.setValue(value);
      sendBase("setProperty", args);
    }

    public void recv_setProperty() throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException
    {
      setProperty_result result = new setProperty_result();
      receiveBase(result, "setProperty");
      if (result.ouch1 != null) {
        throw result.ouch1;
      }
      if (result.ouch2 != null) {
        throw result.ouch2;
      }
      return;
    }

    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(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);
      args.setClassName(className);
      args.setAsTypeName(asTypeName);
      sendBase("testClassLoad", args);
    }

    public boolean recv_testClassLoad() throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException
    {
      testClassLoad_result result = new testClassLoad_result();
      receiveBase(result, "testClassLoad");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ouch1 != null) {
        throw result.ouch1;
      }
      if (result.ouch2 != null) {
        throw result.ouch2;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "testClassLoad failed: unknown result");
    }

    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(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);
      args.setUser(user);
      args.setProperties(properties);
      sendBase("authenticateUser", args);
    }

    public boolean recv_authenticateUser() throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException
    {
      authenticateUser_result result = new authenticateUser_result();
      receiveBase(result, "authenticateUser");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ouch1 != null) {
        throw result.ouch1;
      }
      if (result.ouch2 != null) {
        throw result.ouch2;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "authenticateUser failed: unknown result");
    }

    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(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);
      args.setUser(user);
      args.setAuthorizations(authorizations);
      sendBase("changeUserAuthorizations", args);
    }

    public void recv_changeUserAuthorizations() throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException
    {
      changeUserAuthorizations_result result = new changeUserAuthorizations_result();
      receiveBase(result, "changeUserAuthorizations");
      if (result.ouch1 != null) {
        throw result.ouch1;
      }
      if (result.ouch2 != null) {
        throw result.ouch2;
      }
      return;
    }

    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(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);
      args.setUser(user);
      args.setPassword(password);
      sendBase("changeLocalUserPassword", args);
    }

    public void recv_changeLocalUserPassword() throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException
    {
      changeLocalUserPassword_result result = new changeLocalUserPassword_result();
      receiveBase(result, "changeLocalUserPassword");
      if (result.ouch1 != null) {
        throw result.ouch1;
      }
      if (result.ouch2 != null) {
        throw result.ouch2;
      }
      return;
    }

    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(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);
      args.setUser(user);
      args.setPassword(password);
      sendBase("createLocalUser", args);
    }

    public void recv_createLocalUser() throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException
    {
      createLocalUser_result result = new createLocalUser_result();
      receiveBase(result, "createLocalUser");
      if (result.ouch1 != null) {
        throw result.ouch1;
      }
      if (result.ouch2 != null) {
        throw result.ouch2;
      }
      return;
    }

    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(java.nio.ByteBuffer login, java.lang.String user) throws org.apache.thrift.TException
    {
      dropLocalUser_args args = new dropLocalUser_args();
      args.setLogin(login);
      args.setUser(user);
      sendBase("dropLocalUser", args);
    }

    public void recv_dropLocalUser() throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException
    {
      dropLocalUser_result result = new dropLocalUser_result();
      receiveBase(result, "dropLocalUser");
      if (result.ouch1 != null) {
        throw result.ouch1;
      }
      if (result.ouch2 != null) {
        throw result.ouch2;
      }
      return;
    }

    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(java.nio.ByteBuffer login, java.lang.String user) throws org.apache.thrift.TException
    {
      getUserAuthorizations_args args = new getUserAuthorizations_args();
      args.setLogin(login);
      args.setUser(user);
      sendBase("getUserAuthorizations", args);
    }

    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");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ouch1 != null) {
        throw result.ouch1;
      }
      if (result.ouch2 != null) {
        throw result.ouch2;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getUserAuthorizations failed: unknown result");
    }

    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(java.nio.ByteBuffer login, java.lang.String user, SystemPermission perm) throws org.apache.thrift.TException
    {
      grantSystemPermission_args args = new grantSystemPermission_args();
      args.setLogin(login);
      args.setUser(user);
      args.setPerm(perm);
      sendBase("grantSystemPermission", args);
    }

    public void recv_grantSystemPermission() throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException
    {
      grantSystemPermission_result result = new grantSystemPermission_result();
      receiveBase(result, "grantSystemPermission");
      if (result.ouch1 != null) {
        throw result.ouch1;
      }
      if (result.ouch2 != null) {
        throw result.ouch2;
      }
      return;
    }

    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(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);
      args.setUser(user);
      args.setTable(table);
      args.setPerm(perm);
      sendBase("grantTablePermission", args);
    }

    public void recv_grantTablePermission() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
    {
      grantTablePermission_result result = new grantTablePermission_result();
      receiveBase(result, "grantTablePermission");
      if (result.ouch1 != null) {
        throw result.ouch1;
      }
      if (result.ouch2 != null) {
        throw result.ouch2;
      }
      if (result.ouch3 != null) {
        throw result.ouch3;
      }
      return;
    }

    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(java.nio.ByteBuffer login, java.lang.String user, SystemPermission perm) throws org.apache.thrift.TException
    {
      hasSystemPermission_args args = new hasSystemPermission_args();
      args.setLogin(login);
      args.setUser(user);
      args.setPerm(perm);
      sendBase("hasSystemPermission", args);
    }

    public boolean recv_hasSystemPermission() throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException
    {
      hasSystemPermission_result result = new hasSystemPermission_result();
      receiveBase(result, "hasSystemPermission");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ouch1 != null) {
        throw result.ouch1;
      }
      if (result.ouch2 != null) {
        throw result.ouch2;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "hasSystemPermission failed: unknown result");
    }

    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(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);
      args.setUser(user);
      args.setTable(table);
      args.setPerm(perm);
      sendBase("hasTablePermission", args);
    }

    public boolean recv_hasTablePermission() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
    {
      hasTablePermission_result result = new hasTablePermission_result();
      receiveBase(result, "hasTablePermission");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ouch1 != null) {
        throw result.ouch1;
      }
      if (result.ouch2 != null) {
        throw result.ouch2;
      }
      if (result.ouch3 != null) {
        throw result.ouch3;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "hasTablePermission failed: unknown result");
    }

    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(java.nio.ByteBuffer login) throws org.apache.thrift.TException
    {
      listLocalUsers_args args = new listLocalUsers_args();
      args.setLogin(login);
      sendBase("listLocalUsers", args);
    }

    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");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ouch1 != null) {
        throw result.ouch1;
      }
      if (result.ouch2 != null) {
        throw result.ouch2;
      }
      if (result.ouch3 != null) {
        throw result.ouch3;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "listLocalUsers failed: unknown result");
    }

    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(java.nio.ByteBuffer login, java.lang.String user, SystemPermission perm) throws org.apache.thrift.TException
    {
      revokeSystemPermission_args args = new revokeSystemPermission_args();
      args.setLogin(login);
      args.setUser(user);
      args.setPerm(perm);
      sendBase("revokeSystemPermission", args);
    }

    public void recv_revokeSystemPermission() throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException
    {
      revokeSystemPermission_result result = new revokeSystemPermission_result();
      receiveBase(result, "revokeSystemPermission");
      if (result.ouch1 != null) {
        throw result.ouch1;
      }
      if (result.ouch2 != null) {
        throw result.ouch2;
      }
      return;
    }

    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(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);
      args.setUser(user);
      args.setTable(table);
      args.setPerm(perm);
      sendBase("revokeTablePermission", args);
    }

    public void recv_revokeTablePermission() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
    {
      revokeTablePermission_result result = new revokeTablePermission_result();
      receiveBase(result, "revokeTablePermission");
      if (result.ouch1 != null) {
        throw result.ouch1;
      }
      if (result.ouch2 != null) {
        throw result.ouch2;
      }
      if (result.ouch3 != null) {
        throw result.ouch3;
      }
      return;
    }

    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(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);
      args.setUser(user);
      args.setNamespaceName(namespaceName);
      args.setPerm(perm);
      sendBase("grantNamespacePermission", args);
    }

    public void recv_grantNamespacePermission() throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException
    {
      grantNamespacePermission_result result = new grantNamespacePermission_result();
      receiveBase(result, "grantNamespacePermission");
      if (result.ouch1 != null) {
        throw result.ouch1;
      }
      if (result.ouch2 != null) {
        throw result.ouch2;
      }
      return;
    }

    public boolean hasNamespacePermission(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(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);
      args.setUser(user);
      args.setNamespaceName(namespaceName);
      args.setPerm(perm);
      sendBase("hasNamespacePermission", args);
    }

    public boolean recv_hasNamespacePermission() throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException
    {
      hasNamespacePermission_result result = new hasNamespacePermission_result();
      receiveBase(result, "hasNamespacePermission");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ouch1 != null) {
        throw result.ouch1;
      }
      if (result.ouch2 != null) {
        throw result.ouch2;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "hasNamespacePermission failed: unknown result");
    }

    public void revokeNamespacePermission(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(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);
      args.setUser(user);
      args.setNamespaceName(namespaceName);
      args.setPerm(perm);
      sendBase("revokeNamespacePermission", args);
    }

    public void recv_revokeNamespacePermission() throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException
    {
      revokeNamespacePermission_result result = new revokeNamespacePermission_result();
      receiveBase(result, "revokeNamespacePermission");
      if (result.ouch1 != null) {
        throw result.ouch1;
      }
      if (result.ouch2 != null) {
        throw result.ouch2;
      }
      return;
    }

    public 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(java.nio.ByteBuffer login, java.lang.String tableName, BatchScanOptions options) throws org.apache.thrift.TException
    {
      createBatchScanner_args args = new createBatchScanner_args();
      args.setLogin(login);
      args.setTableName(tableName);
      args.setOptions(options);
      sendBase("createBatchScanner", args);
    }

    public java.lang.String recv_createBatchScanner() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
    {
      createBatchScanner_result result = new createBatchScanner_result();
      receiveBase(result, "createBatchScanner");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ouch1 != null) {
        throw result.ouch1;
      }
      if (result.ouch2 != null) {
        throw result.ouch2;
      }
      if (result.ouch3 != null) {
        throw result.ouch3;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "createBatchScanner failed: unknown result");
    }

    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(java.nio.ByteBuffer login, java.lang.String tableName, ScanOptions options) throws org.apache.thrift.TException
    {
      createScanner_args args = new createScanner_args();
      args.setLogin(login);
      args.setTableName(tableName);
      args.setOptions(options);
      sendBase("createScanner", args);
    }

    public java.lang.String recv_createScanner() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
    {
      createScanner_result result = new createScanner_result();
      receiveBase(result, "createScanner");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ouch1 != null) {
        throw result.ouch1;
      }
      if (result.ouch2 != null) {
        throw result.ouch2;
      }
      if (result.ouch3 != null) {
        throw result.ouch3;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "createScanner failed: unknown result");
    }

    public boolean hasNext(java.lang.String scanner) throws UnknownScanner, org.apache.thrift.TException
    {
      send_hasNext(scanner);
      return recv_hasNext();
    }

    public void send_hasNext(java.lang.String scanner) throws org.apache.thrift.TException
    {
      hasNext_args args = new hasNext_args();
      args.setScanner(scanner);
      sendBase("hasNext", args);
    }

    public boolean recv_hasNext() throws UnknownScanner, org.apache.thrift.TException
    {
      hasNext_result result = new hasNext_result();
      receiveBase(result, "hasNext");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ouch1 != null) {
        throw result.ouch1;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "hasNext failed: unknown result");
    }

    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(java.lang.String scanner) throws org.apache.thrift.TException
    {
      nextEntry_args args = new nextEntry_args();
      args.setScanner(scanner);
      sendBase("nextEntry", args);
    }

    public KeyValueAndPeek recv_nextEntry() throws NoMoreEntriesException, UnknownScanner, AccumuloSecurityException, org.apache.thrift.TException
    {
      nextEntry_result result = new nextEntry_result();
      receiveBase(result, "nextEntry");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ouch1 != null) {
        throw result.ouch1;
      }
      if (result.ouch2 != null) {
        throw result.ouch2;
      }
      if (result.ouch3 != null) {
        throw result.ouch3;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "nextEntry failed: unknown result");
    }

    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(java.lang.String scanner, int k) throws org.apache.thrift.TException
    {
      nextK_args args = new nextK_args();
      args.setScanner(scanner);
      args.setK(k);
      sendBase("nextK", args);
    }

    public ScanResult recv_nextK() throws NoMoreEntriesException, UnknownScanner, AccumuloSecurityException, org.apache.thrift.TException
    {
      nextK_result result = new nextK_result();
      receiveBase(result, "nextK");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ouch1 != null) {
        throw result.ouch1;
      }
      if (result.ouch2 != null) {
        throw result.ouch2;
      }
      if (result.ouch3 != null) {
        throw result.ouch3;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "nextK failed: unknown result");
    }

    public void closeScanner(java.lang.String scanner) throws UnknownScanner, org.apache.thrift.TException
    {
      send_closeScanner(scanner);
      recv_closeScanner();
    }

    public void send_closeScanner(java.lang.String scanner) throws org.apache.thrift.TException
    {
      closeScanner_args args = new closeScanner_args();
      args.setScanner(scanner);
      sendBase("closeScanner", args);
    }

    public void recv_closeScanner() throws UnknownScanner, org.apache.thrift.TException
    {
      closeScanner_result result = new closeScanner_result();
      receiveBase(result, "closeScanner");
      if (result.ouch1 != null) {
        throw result.ouch1;
      }
      return;
    }

    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(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);
      args.setTableName(tableName);
      args.setCells(cells);
      sendBase("updateAndFlush", args);
    }

    public void recv_updateAndFlush() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, MutationsRejectedException, org.apache.thrift.TException
    {
      updateAndFlush_result result = new updateAndFlush_result();
      receiveBase(result, "updateAndFlush");
      if (result.outch1 != null) {
        throw result.outch1;
      }
      if (result.ouch2 != null) {
        throw result.ouch2;
      }
      if (result.ouch3 != null) {
        throw result.ouch3;
      }
      if (result.ouch4 != null) {
        throw result.ouch4;
      }
      return;
    }

    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(java.nio.ByteBuffer login, java.lang.String tableName, WriterOptions opts) throws org.apache.thrift.TException
    {
      createWriter_args args = new createWriter_args();
      args.setLogin(login);
      args.setTableName(tableName);
      args.setOpts(opts);
      sendBase("createWriter", args);
    }

    public java.lang.String recv_createWriter() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
    {
      createWriter_result result = new createWriter_result();
      receiveBase(result, "createWriter");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.outch1 != null) {
        throw result.outch1;
      }
      if (result.ouch2 != null) {
        throw result.ouch2;
      }
      if (result.ouch3 != null) {
        throw result.ouch3;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "createWriter failed: unknown result");
    }

    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(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);
      args.setCells(cells);
      sendBaseOneway("update", args);
    }

    public void flush(java.lang.String writer) throws UnknownWriter, MutationsRejectedException, org.apache.thrift.TException
    {
      send_flush(writer);
      recv_flush();
    }

    public void send_flush(java.lang.String writer) throws org.apache.thrift.TException
    {
      flush_args args = new flush_args();
      args.setWriter(writer);
      sendBase("flush", args);
    }

    public void recv_flush() throws UnknownWriter, MutationsRejectedException, org.apache.thrift.TException
    {
      flush_result result = new flush_result();
      receiveBase(result, "flush");
      if (result.ouch1 != null) {
        throw result.ouch1;
      }
      if (result.ouch2 != null) {
        throw result.ouch2;
      }
      return;
    }

    public void closeWriter(java.lang.String writer) throws UnknownWriter, MutationsRejectedException, org.apache.thrift.TException
    {
      send_closeWriter(writer);
      recv_closeWriter();
    }

    public void send_closeWriter(java.lang.String writer) throws org.apache.thrift.TException
    {
      closeWriter_args args = new closeWriter_args();
      args.setWriter(writer);
      sendBase("closeWriter", args);
    }

    public void recv_closeWriter() throws UnknownWriter, MutationsRejectedException, org.apache.thrift.TException
    {
      closeWriter_result result = new closeWriter_result();
      receiveBase(result, "closeWriter");
      if (result.ouch1 != null) {
        throw result.ouch1;
      }
      if (result.ouch2 != null) {
        throw result.ouch2;
      }
      return;
    }

    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(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);
      args.setTableName(tableName);
      args.setRow(row);
      args.setUpdates(updates);
      sendBase("updateRowConditionally", args);
    }

    public ConditionalStatus recv_updateRowConditionally() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
    {
      updateRowConditionally_result result = new updateRowConditionally_result();
      receiveBase(result, "updateRowConditionally");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ouch1 != null) {
        throw result.ouch1;
      }
      if (result.ouch2 != null) {
        throw result.ouch2;
      }
      if (result.ouch3 != null) {
        throw result.ouch3;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "updateRowConditionally failed: unknown result");
    }

    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(java.nio.ByteBuffer login, java.lang.String tableName, ConditionalWriterOptions options) throws org.apache.thrift.TException
    {
      createConditionalWriter_args args = new createConditionalWriter_args();
      args.setLogin(login);
      args.setTableName(tableName);
      args.setOptions(options);
      sendBase("createConditionalWriter", args);
    }

    public java.lang.String recv_createConditionalWriter() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
    {
      createConditionalWriter_result result = new createConditionalWriter_result();
      receiveBase(result, "createConditionalWriter");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ouch1 != null) {
        throw result.ouch1;
      }
      if (result.ouch2 != null) {
        throw result.ouch2;
      }
      if (result.ouch3 != null) {
        throw result.ouch3;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "createConditionalWriter failed: unknown result");
    }

    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(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);
      args.setUpdates(updates);
      sendBase("updateRowsConditionally", args);
    }

    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");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ouch1 != null) {
        throw result.ouch1;
      }
      if (result.ouch2 != null) {
        throw result.ouch2;
      }
      if (result.ouch3 != null) {
        throw result.ouch3;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "updateRowsConditionally failed: unknown result");
    }

    public void closeConditionalWriter(java.lang.String conditionalWriter) throws org.apache.thrift.TException
    {
      send_closeConditionalWriter(conditionalWriter);
      recv_closeConditionalWriter();
    }

    public void send_closeConditionalWriter(java.lang.String conditionalWriter) throws org.apache.thrift.TException
    {
      closeConditionalWriter_args args = new closeConditionalWriter_args();
      args.setConditionalWriter(conditionalWriter);
      sendBase("closeConditionalWriter", args);
    }

    public void recv_closeConditionalWriter() throws org.apache.thrift.TException
    {
      closeConditionalWriter_result result = new closeConditionalWriter_result();
      receiveBase(result, "closeConditionalWriter");
      return;
    }

    public Range getRowRange(java.nio.ByteBuffer row) throws org.apache.thrift.TException
    {
      send_getRowRange(row);
      return recv_getRowRange();
    }

    public void send_getRowRange(java.nio.ByteBuffer row) throws org.apache.thrift.TException
    {
      getRowRange_args args = new getRowRange_args();
      args.setRow(row);
      sendBase("getRowRange", args);
    }

    public Range recv_getRowRange() throws org.apache.thrift.TException
    {
      getRowRange_result result = new getRowRange_result();
      receiveBase(result, "getRowRange");
      if (result.isSetSuccess()) {
        return result.success;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getRowRange failed: unknown result");
    }

    public Key getFollowing(Key key, PartialKey part) throws org.apache.thrift.TException
    {
      send_getFollowing(key, part);
      return recv_getFollowing();
    }

    public void send_getFollowing(Key key, PartialKey part) throws org.apache.thrift.TException
    {
      getFollowing_args args = new getFollowing_args();
      args.setKey(key);
      args.setPart(part);
      sendBase("getFollowing", args);
    }

    public Key recv_getFollowing() throws org.apache.thrift.TException
    {
      getFollowing_result result = new getFollowing_result();
      receiveBase(result, "getFollowing");
      if (result.isSetSuccess()) {
        return result.success;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getFollowing failed: unknown result");
    }

    public java.lang.String systemNamespace() throws org.apache.thrift.TException
    {
      send_systemNamespace();
      return recv_systemNamespace();
    }

    public void send_systemNamespace() throws org.apache.thrift.TException
    {
      systemNamespace_args args = new systemNamespace_args();
      sendBase("systemNamespace", args);
    }

    public java.lang.String recv_systemNamespace() throws org.apache.thrift.TException
    {
      systemNamespace_result result = new systemNamespace_result();
      receiveBase(result, "systemNamespace");
      if (result.isSetSuccess()) {
        return result.success;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "systemNamespace failed: unknown result");
    }

    public java.lang.String defaultNamespace() throws org.apache.thrift.TException
    {
      send_defaultNamespace();
      return recv_defaultNamespace();
    }

    public void send_defaultNamespace() throws org.apache.thrift.TException
    {
      defaultNamespace_args args = new defaultNamespace_args();
      sendBase("defaultNamespace", args);
    }

    public java.lang.String recv_defaultNamespace() throws org.apache.thrift.TException
    {
      defaultNamespace_result result = new defaultNamespace_result();
      receiveBase(result, "defaultNamespace");
      if (result.isSetSuccess()) {
        return result.success;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "defaultNamespace failed: unknown result");
    }

    public 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(java.nio.ByteBuffer login) throws org.apache.thrift.TException
    {
      listNamespaces_args args = new listNamespaces_args();
      args.setLogin(login);
      sendBase("listNamespaces", args);
    }

    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");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ouch1 != null) {
        throw result.ouch1;
      }
      if (result.ouch2 != null) {
        throw result.ouch2;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "listNamespaces failed: unknown result");
    }

    public boolean namespaceExists(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(java.nio.ByteBuffer login, java.lang.String namespaceName) throws org.apache.thrift.TException
    {
      namespaceExists_args args = new namespaceExists_args();
      args.setLogin(login);
      args.setNamespaceName(namespaceName);
      sendBase("namespaceExists", args);
    }

    public boolean recv_namespaceExists() throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException
    {
      namespaceExists_result result = new namespaceExists_result();
      receiveBase(result, "namespaceExists");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ouch1 != null) {
        throw result.ouch1;
      }
      if (result.ouch2 != null) {
        throw result.ouch2;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "namespaceExists failed: unknown result");
    }

    public void createNamespace(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(java.nio.ByteBuffer login, java.lang.String namespaceName) throws org.apache.thrift.TException
    {
      createNamespace_args args = new createNamespace_args();
      args.setLogin(login);
      args.setNamespaceName(namespaceName);
      sendBase("createNamespace", args);
    }

    public void recv_createNamespace() throws AccumuloException, AccumuloSecurityException, NamespaceExistsException, org.apache.thrift.TException
    {
      createNamespace_result result = new createNamespace_result();
      receiveBase(result, "createNamespace");
      if (result.ouch1 != null) {
        throw result.ouch1;
      }
      if (result.ouch2 != null) {
        throw result.ouch2;
      }
      if (result.ouch3 != null) {
        throw result.ouch3;
      }
      return;
    }

    public void deleteNamespace(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(java.nio.ByteBuffer login, java.lang.String namespaceName) throws org.apache.thrift.TException
    {
      deleteNamespace_args args = new deleteNamespace_args();
      args.setLogin(login);
      args.setNamespaceName(namespaceName);
      sendBase("deleteNamespace", args);
    }

    public void recv_deleteNamespace() throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, NamespaceNotEmptyException, org.apache.thrift.TException
    {
      deleteNamespace_result result = new deleteNamespace_result();
      receiveBase(result, "deleteNamespace");
      if (result.ouch1 != null) {
        throw result.ouch1;
      }
      if (result.ouch2 != null) {
        throw result.ouch2;
      }
      if (result.ouch3 != null) {
        throw result.ouch3;
      }
      if (result.ouch4 != null) {
        throw result.ouch4;
      }
      return;
    }

    public void renameNamespace(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(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);
      args.setOldNamespaceName(oldNamespaceName);
      args.setNewNamespaceName(newNamespaceName);
      sendBase("renameNamespace", args);
    }

    public void recv_renameNamespace() throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, NamespaceExistsException, org.apache.thrift.TException
    {
      renameNamespace_result result = new renameNamespace_result();
      receiveBase(result, "renameNamespace");
      if (result.ouch1 != null) {
        throw result.ouch1;
      }
      if (result.ouch2 != null) {
        throw result.ouch2;
      }
      if (result.ouch3 != null) {
        throw result.ouch3;
      }
      if (result.ouch4 != null) {
        throw result.ouch4;
      }
      return;
    }

    public void setNamespaceProperty(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(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);
      args.setNamespaceName(namespaceName);
      args.setProperty(property);
      args.setValue(value);
      sendBase("setNamespaceProperty", args);
    }

    public void recv_setNamespaceProperty() throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException
    {
      setNamespaceProperty_result result = new setNamespaceProperty_result();
      receiveBase(result, "setNamespaceProperty");
      if (result.ouch1 != null) {
        throw result.ouch1;
      }
      if (result.ouch2 != null) {
        throw result.ouch2;
      }
      if (result.ouch3 != null) {
        throw result.ouch3;
      }
      return;
    }

    public void removeNamespaceProperty(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(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);
      args.setNamespaceName(namespaceName);
      args.setProperty(property);
      sendBase("removeNamespaceProperty", args);
    }

    public void recv_removeNamespaceProperty() throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException
    {
      removeNamespaceProperty_result result = new removeNamespaceProperty_result();
      receiveBase(result, "removeNamespaceProperty");
      if (result.ouch1 != null) {
        throw result.ouch1;
      }
      if (result.ouch2 != null) {
        throw result.ouch2;
      }
      if (result.ouch3 != null) {
        throw result.ouch3;
      }
      return;
    }

    public 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(java.nio.ByteBuffer login, java.lang.String namespaceName) throws org.apache.thrift.TException
    {
      getNamespaceProperties_args args = new getNamespaceProperties_args();
      args.setLogin(login);
      args.setNamespaceName(namespaceName);
      sendBase("getNamespaceProperties", args);
    }

    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");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ouch1 != null) {
        throw result.ouch1;
      }
      if (result.ouch2 != null) {
        throw result.ouch2;
      }
      if (result.ouch3 != null) {
        throw result.ouch3;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getNamespaceProperties failed: unknown result");
    }

    public 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(java.nio.ByteBuffer login) throws org.apache.thrift.TException
    {
      namespaceIdMap_args args = new namespaceIdMap_args();
      args.setLogin(login);
      sendBase("namespaceIdMap", args);
    }

    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");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ouch1 != null) {
        throw result.ouch1;
      }
      if (result.ouch2 != null) {
        throw result.ouch2;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "namespaceIdMap failed: unknown result");
    }

    public void attachNamespaceIterator(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(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);
      args.setNamespaceName(namespaceName);
      args.setSetting(setting);
      args.setScopes(scopes);
      sendBase("attachNamespaceIterator", args);
    }

    public void recv_attachNamespaceIterator() throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException
    {
      attachNamespaceIterator_result result = new attachNamespaceIterator_result();
      receiveBase(result, "attachNamespaceIterator");
      if (result.ouch1 != null) {
        throw result.ouch1;
      }
      if (result.ouch2 != null) {
        throw result.ouch2;
      }
      if (result.ouch3 != null) {
        throw result.ouch3;
      }
      return;
    }

    public void removeNamespaceIterator(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(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);
      args.setNamespaceName(namespaceName);
      args.setName(name);
      args.setScopes(scopes);
      sendBase("removeNamespaceIterator", args);
    }

    public void recv_removeNamespaceIterator() throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException
    {
      removeNamespaceIterator_result result = new removeNamespaceIterator_result();
      receiveBase(result, "removeNamespaceIterator");
      if (result.ouch1 != null) {
        throw result.ouch1;
      }
      if (result.ouch2 != null) {
        throw result.ouch2;
      }
      if (result.ouch3 != null) {
        throw result.ouch3;
      }
      return;
    }

    public IteratorSetting getNamespaceIteratorSetting(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(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);
      args.setNamespaceName(namespaceName);
      args.setName(name);
      args.setScope(scope);
      sendBase("getNamespaceIteratorSetting", args);
    }

    public IteratorSetting recv_getNamespaceIteratorSetting() throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException
    {
      getNamespaceIteratorSetting_result result = new getNamespaceIteratorSetting_result();
      receiveBase(result, "getNamespaceIteratorSetting");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ouch1 != null) {
        throw result.ouch1;
      }
      if (result.ouch2 != null) {
        throw result.ouch2;
      }
      if (result.ouch3 != null) {
        throw result.ouch3;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getNamespaceIteratorSetting failed: unknown result");
    }

    public 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(java.nio.ByteBuffer login, java.lang.String namespaceName) throws org.apache.thrift.TException
    {
      listNamespaceIterators_args args = new listNamespaceIterators_args();
      args.setLogin(login);
      args.setNamespaceName(namespaceName);
      sendBase("listNamespaceIterators", args);
    }

    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");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ouch1 != null) {
        throw result.ouch1;
      }
      if (result.ouch2 != null) {
        throw result.ouch2;
      }
      if (result.ouch3 != null) {
        throw result.ouch3;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "listNamespaceIterators failed: unknown result");
    }

    public void checkNamespaceIteratorConflicts(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(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);
      args.setNamespaceName(namespaceName);
      args.setSetting(setting);
      args.setScopes(scopes);
      sendBase("checkNamespaceIteratorConflicts", args);
    }

    public void recv_checkNamespaceIteratorConflicts() throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException
    {
      checkNamespaceIteratorConflicts_result result = new checkNamespaceIteratorConflicts_result();
      receiveBase(result, "checkNamespaceIteratorConflicts");
      if (result.ouch1 != null) {
        throw result.ouch1;
      }
      if (result.ouch2 != null) {
        throw result.ouch2;
      }
      if (result.ouch3 != null) {
        throw result.ouch3;
      }
      return;
    }

    public int addNamespaceConstraint(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(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);
      args.setNamespaceName(namespaceName);
      args.setConstraintClassName(constraintClassName);
      sendBase("addNamespaceConstraint", args);
    }

    public int recv_addNamespaceConstraint() throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException
    {
      addNamespaceConstraint_result result = new addNamespaceConstraint_result();
      receiveBase(result, "addNamespaceConstraint");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ouch1 != null) {
        throw result.ouch1;
      }
      if (result.ouch2 != null) {
        throw result.ouch2;
      }
      if (result.ouch3 != null) {
        throw result.ouch3;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "addNamespaceConstraint failed: unknown result");
    }

    public void removeNamespaceConstraint(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(java.nio.ByteBuffer login, java.lang.String namespaceName, int id) throws org.apache.thrift.TException
    {
      removeNamespaceConstraint_args args = new removeNamespaceConstraint_args();
      args.setLogin(login);
      args.setNamespaceName(namespaceName);
      args.setId(id);
      sendBase("removeNamespaceConstraint", args);
    }

    public void recv_removeNamespaceConstraint() throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException
    {
      removeNamespaceConstraint_result result = new removeNamespaceConstraint_result();
      receiveBase(result, "removeNamespaceConstraint");
      if (result.ouch1 != null) {
        throw result.ouch1;
      }
      if (result.ouch2 != null) {
        throw result.ouch2;
      }
      if (result.ouch3 != null) {
        throw result.ouch3;
      }
      return;
    }

    public 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(java.nio.ByteBuffer login, java.lang.String namespaceName) throws org.apache.thrift.TException
    {
      listNamespaceConstraints_args args = new listNamespaceConstraints_args();
      args.setLogin(login);
      args.setNamespaceName(namespaceName);
      sendBase("listNamespaceConstraints", args);
    }

    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");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ouch1 != null) {
        throw result.ouch1;
      }
      if (result.ouch2 != null) {
        throw result.ouch2;
      }
      if (result.ouch3 != null) {
        throw result.ouch3;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "listNamespaceConstraints failed: unknown result");
    }

    public boolean testNamespaceClassLoad(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(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);
      args.setNamespaceName(namespaceName);
      args.setClassName(className);
      args.setAsTypeName(asTypeName);
      sendBase("testNamespaceClassLoad", args);
    }

    public boolean recv_testNamespaceClassLoad() throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException
    {
      testNamespaceClassLoad_result result = new testNamespaceClassLoad_result();
      receiveBase(result, "testNamespaceClassLoad");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ouch1 != null) {
        throw result.ouch1;
      }
      if (result.ouch2 != null) {
        throw result.ouch2;
      }
      if (result.ouch3 != null) {
        throw result.ouch3;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "testNamespaceClassLoad failed: unknown result");
    }

  }
  public static class AsyncClient extends org.apache.thrift.async.TAsyncClient implements AsyncIface {
    public static class Factory implements org.apache.thrift.async.TAsyncClientFactory<AsyncClient> {
      private org.apache.thrift.async.TAsyncClientManager clientManager;
      private org.apache.thrift.protocol.TProtocolFactory protocolFactory;
      public Factory(org.apache.thrift.async.TAsyncClientManager clientManager, org.apache.thrift.protocol.TProtocolFactory protocolFactory) {
        this.clientManager = clientManager;
        this.protocolFactory = protocolFactory;
      }
      public AsyncClient getAsyncClient(org.apache.thrift.transport.TNonblockingTransport transport) {
        return new AsyncClient(protocolFactory, clientManager, transport);
      }
    }

    public AsyncClient(org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.async.TAsyncClientManager clientManager, org.apache.thrift.transport.TNonblockingTransport transport) {
      super(protocolFactory, clientManager, transport);
    }

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

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("login", org.apache.thrift.protocol.TMessageType.CALL, 0));
        login_args args = new login_args();
        args.setPrincipal(principal);
        args.setLoginProperties(loginProperties);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public java.nio.ByteBuffer getResult() throws AccumuloSecurityException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          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 (new Client(prot)).recv_login();
      }
    }

    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<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;
        this.constraintClassName = constraintClassName;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("addConstraint", org.apache.thrift.protocol.TMessageType.CALL, 0));
        addConstraint_args args = new addConstraint_args();
        args.setLogin(login);
        args.setTableName(tableName);
        args.setConstraintClassName(constraintClassName);
        args.write(prot);
        prot.writeMessageEnd();
      }

      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 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 (new Client(prot)).recv_addConstraint();
      }
    }

    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<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;
        this.splits = splits;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("addSplits", org.apache.thrift.protocol.TMessageType.CALL, 0));
        addSplits_args args = new addSplits_args();
        args.setLogin(login);
        args.setTableName(tableName);
        args.setSplits(splits);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public Void getResult() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          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 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<Void> {
      private java.nio.ByteBuffer login;
      private java.lang.String tableName;
      private IteratorSetting setting;
      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;
        this.setting = setting;
        this.scopes = scopes;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("attachIterator", org.apache.thrift.protocol.TMessageType.CALL, 0));
        attachIterator_args args = new attachIterator_args();
        args.setLogin(login);
        args.setTableName(tableName);
        args.setSetting(setting);
        args.setScopes(scopes);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public Void getResult() throws AccumuloSecurityException, AccumuloException, TableNotFoundException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          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 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<Void> {
      private java.nio.ByteBuffer login;
      private java.lang.String tableName;
      private IteratorSetting setting;
      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;
        this.setting = setting;
        this.scopes = scopes;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("checkIteratorConflicts", org.apache.thrift.protocol.TMessageType.CALL, 0));
        checkIteratorConflicts_args args = new checkIteratorConflicts_args();
        args.setLogin(login);
        args.setTableName(tableName);
        args.setSetting(setting);
        args.setScopes(scopes);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public Void getResult() throws AccumuloSecurityException, AccumuloException, TableNotFoundException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          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 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<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;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("clearLocatorCache", org.apache.thrift.protocol.TMessageType.CALL, 0));
        clearLocatorCache_args args = new clearLocatorCache_args();
        args.setLogin(login);
        args.setTableName(tableName);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public Void getResult() throws TableNotFoundException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          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 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<Void> {
      private java.nio.ByteBuffer login;
      private java.lang.String tableName;
      private java.lang.String newTableName;
      private boolean flush;
      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;
        this.newTableName = newTableName;
        this.flush = flush;
        this.propertiesToSet = propertiesToSet;
        this.propertiesToExclude = propertiesToExclude;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("cloneTable", org.apache.thrift.protocol.TMessageType.CALL, 0));
        cloneTable_args args = new cloneTable_args();
        args.setLogin(login);
        args.setTableName(tableName);
        args.setNewTableName(newTableName);
        args.setFlush(flush);
        args.setPropertiesToSet(propertiesToSet);
        args.setPropertiesToExclude(propertiesToExclude);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public Void getResult() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, TableExistsException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          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 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<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(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;
        this.startRow = startRow;
        this.endRow = endRow;
        this.iterators = iterators;
        this.flush = flush;
        this.wait = wait;
        this.compactionStrategy = compactionStrategy;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("compactTable", org.apache.thrift.protocol.TMessageType.CALL, 0));
        compactTable_args args = new compactTable_args();
        args.setLogin(login);
        args.setTableName(tableName);
        args.setStartRow(startRow);
        args.setEndRow(endRow);
        args.setIterators(iterators);
        args.setFlush(flush);
        args.setWait(wait);
        args.setCompactionStrategy(compactionStrategy);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public Void getResult() throws AccumuloSecurityException, TableNotFoundException, AccumuloException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          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 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<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;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("cancelCompaction", org.apache.thrift.protocol.TMessageType.CALL, 0));
        cancelCompaction_args args = new cancelCompaction_args();
        args.setLogin(login);
        args.setTableName(tableName);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public Void getResult() throws AccumuloSecurityException, TableNotFoundException, AccumuloException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          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 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<Void> {
      private java.nio.ByteBuffer login;
      private java.lang.String tableName;
      private boolean versioningIter;
      private TimeType type;
      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;
        this.versioningIter = versioningIter;
        this.type = type;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("createTable", org.apache.thrift.protocol.TMessageType.CALL, 0));
        createTable_args args = new createTable_args();
        args.setLogin(login);
        args.setTableName(tableName);
        args.setVersioningIter(versioningIter);
        args.setType(type);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public Void getResult() throws AccumuloException, AccumuloSecurityException, TableExistsException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          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 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<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;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("deleteTable", org.apache.thrift.protocol.TMessageType.CALL, 0));
        deleteTable_args args = new deleteTable_args();
        args.setLogin(login);
        args.setTableName(tableName);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public Void getResult() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          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 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<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;
        this.startRow = startRow;
        this.endRow = endRow;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("deleteRows", org.apache.thrift.protocol.TMessageType.CALL, 0));
        deleteRows_args args = new deleteRows_args();
        args.setLogin(login);
        args.setTableName(tableName);
        args.setStartRow(startRow);
        args.setEndRow(endRow);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public Void getResult() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          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 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<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;
        this.exportDir = exportDir;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("exportTable", org.apache.thrift.protocol.TMessageType.CALL, 0));
        exportTable_args args = new exportTable_args();
        args.setLogin(login);
        args.setTableName(tableName);
        args.setExportDir(exportDir);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public Void getResult() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          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 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<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(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;
        this.startRow = startRow;
        this.endRow = endRow;
        this.wait = wait;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("flushTable", org.apache.thrift.protocol.TMessageType.CALL, 0));
        flushTable_args args = new flushTable_args();
        args.setLogin(login);
        args.setTableName(tableName);
        args.setStartRow(startRow);
        args.setEndRow(endRow);
        args.setWait(wait);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public Void getResult() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          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 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<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;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("getDiskUsage", org.apache.thrift.protocol.TMessageType.CALL, 0));
        getDiskUsage_args args = new getDiskUsage_args();
        args.setLogin(login);
        args.setTables(tables);
        args.write(prot);
        prot.writeMessageEnd();
      }

      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 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 (new Client(prot)).recv_getDiskUsage();
      }
    }

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

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("getLocalityGroups", org.apache.thrift.protocol.TMessageType.CALL, 0));
        getLocalityGroups_args args = new getLocalityGroups_args();
        args.setLogin(login);
        args.setTableName(tableName);
        args.write(prot);
        prot.writeMessageEnd();
      }

      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 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 (new Client(prot)).recv_getLocalityGroups();
      }
    }

    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<IteratorSetting> {
      private java.nio.ByteBuffer login;
      private java.lang.String tableName;
      private java.lang.String iteratorName;
      private IteratorScope scope;
      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;
        this.iteratorName = iteratorName;
        this.scope = scope;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("getIteratorSetting", org.apache.thrift.protocol.TMessageType.CALL, 0));
        getIteratorSetting_args args = new getIteratorSetting_args();
        args.setLogin(login);
        args.setTableName(tableName);
        args.setIteratorName(iteratorName);
        args.setScope(scope);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public IteratorSetting getResult() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          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 (new Client(prot)).recv_getIteratorSetting();
      }
    }

    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<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 java.nio.ByteBuffer endRow;
      private boolean endInclusive;
      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;
        this.auths = auths;
        this.startRow = startRow;
        this.startInclusive = startInclusive;
        this.endRow = endRow;
        this.endInclusive = endInclusive;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("getMaxRow", org.apache.thrift.protocol.TMessageType.CALL, 0));
        getMaxRow_args args = new getMaxRow_args();
        args.setLogin(login);
        args.setTableName(tableName);
        args.setAuths(auths);
        args.setStartRow(startRow);
        args.setStartInclusive(startInclusive);
        args.setEndRow(endRow);
        args.setEndInclusive(endInclusive);
        args.write(prot);
        prot.writeMessageEnd();
      }

      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 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 (new Client(prot)).recv_getMaxRow();
      }
    }

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

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("getTableProperties", org.apache.thrift.protocol.TMessageType.CALL, 0));
        getTableProperties_args args = new getTableProperties_args();
        args.setLogin(login);
        args.setTableName(tableName);
        args.write(prot);
        prot.writeMessageEnd();
      }

      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 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 (new Client(prot)).recv_getTableProperties();
      }
    }

    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<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(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;
        this.importDir = importDir;
        this.failureDir = failureDir;
        this.setTime = setTime;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("importDirectory", org.apache.thrift.protocol.TMessageType.CALL, 0));
        importDirectory_args args = new importDirectory_args();
        args.setLogin(login);
        args.setTableName(tableName);
        args.setImportDir(importDir);
        args.setFailureDir(failureDir);
        args.setSetTime(setTime);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public Void getResult() throws TableNotFoundException, AccumuloException, AccumuloSecurityException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          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 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<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;
        this.importDir = importDir;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("importTable", org.apache.thrift.protocol.TMessageType.CALL, 0));
        importTable_args args = new importTable_args();
        args.setLogin(login);
        args.setTableName(tableName);
        args.setImportDir(importDir);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public Void getResult() throws TableExistsException, AccumuloException, AccumuloSecurityException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          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 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<java.util.List<java.nio.ByteBuffer>> {
      private java.nio.ByteBuffer login;
      private java.lang.String tableName;
      private int maxSplits;
      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;
        this.maxSplits = maxSplits;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("listSplits", org.apache.thrift.protocol.TMessageType.CALL, 0));
        listSplits_args args = new listSplits_args();
        args.setLogin(login);
        args.setTableName(tableName);
        args.setMaxSplits(maxSplits);
        args.write(prot);
        prot.writeMessageEnd();
      }

      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 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 (new Client(prot)).recv_listSplits();
      }
    }

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

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("listTables", org.apache.thrift.protocol.TMessageType.CALL, 0));
        listTables_args args = new listTables_args();
        args.setLogin(login);
        args.write(prot);
        prot.writeMessageEnd();
      }

      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 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 (new Client(prot)).recv_listTables();
      }
    }

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

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("listIterators", org.apache.thrift.protocol.TMessageType.CALL, 0));
        listIterators_args args = new listIterators_args();
        args.setLogin(login);
        args.setTableName(tableName);
        args.write(prot);
        prot.writeMessageEnd();
      }

      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 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 (new Client(prot)).recv_listIterators();
      }
    }

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

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("listConstraints", org.apache.thrift.protocol.TMessageType.CALL, 0));
        listConstraints_args args = new listConstraints_args();
        args.setLogin(login);
        args.setTableName(tableName);
        args.write(prot);
        prot.writeMessageEnd();
      }

      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 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 (new Client(prot)).recv_listConstraints();
      }
    }

    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<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;
        this.startRow = startRow;
        this.endRow = endRow;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("mergeTablets", org.apache.thrift.protocol.TMessageType.CALL, 0));
        mergeTablets_args args = new mergeTablets_args();
        args.setLogin(login);
        args.setTableName(tableName);
        args.setStartRow(startRow);
        args.setEndRow(endRow);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public Void getResult() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          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 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<Void> {
      private java.nio.ByteBuffer login;
      private java.lang.String tableName;
      private boolean wait;
      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;
        this.wait = wait;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("offlineTable", org.apache.thrift.protocol.TMessageType.CALL, 0));
        offlineTable_args args = new offlineTable_args();
        args.setLogin(login);
        args.setTableName(tableName);
        args.setWait(wait);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public Void getResult() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          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 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<Void> {
      private java.nio.ByteBuffer login;
      private java.lang.String tableName;
      private boolean wait;
      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;
        this.wait = wait;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("onlineTable", org.apache.thrift.protocol.TMessageType.CALL, 0));
        onlineTable_args args = new onlineTable_args();
        args.setLogin(login);
        args.setTableName(tableName);
        args.setWait(wait);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public Void getResult() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          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 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<Void> {
      private java.nio.ByteBuffer login;
      private java.lang.String tableName;
      private int constraint;
      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;
        this.constraint = constraint;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("removeConstraint", org.apache.thrift.protocol.TMessageType.CALL, 0));
        removeConstraint_args args = new removeConstraint_args();
        args.setLogin(login);
        args.setTableName(tableName);
        args.setConstraint(constraint);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public Void getResult() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          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 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<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;
        this.iterName = iterName;
        this.scopes = scopes;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("removeIterator", org.apache.thrift.protocol.TMessageType.CALL, 0));
        removeIterator_args args = new removeIterator_args();
        args.setLogin(login);
        args.setTableName(tableName);
        args.setIterName(iterName);
        args.setScopes(scopes);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public Void getResult() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          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 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<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;
        this.property = property;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("removeTableProperty", org.apache.thrift.protocol.TMessageType.CALL, 0));
        removeTableProperty_args args = new removeTableProperty_args();
        args.setLogin(login);
        args.setTableName(tableName);
        args.setProperty(property);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public Void getResult() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          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 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<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;
        this.newTableName = newTableName;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("renameTable", org.apache.thrift.protocol.TMessageType.CALL, 0));
        renameTable_args args = new renameTable_args();
        args.setLogin(login);
        args.setOldTableName(oldTableName);
        args.setNewTableName(newTableName);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public Void getResult() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, TableExistsException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          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 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<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;
        this.groups = groups;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("setLocalityGroups", org.apache.thrift.protocol.TMessageType.CALL, 0));
        setLocalityGroups_args args = new setLocalityGroups_args();
        args.setLogin(login);
        args.setTableName(tableName);
        args.setGroups(groups);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public Void getResult() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          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 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<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;
        this.property = property;
        this.value = value;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("setTableProperty", org.apache.thrift.protocol.TMessageType.CALL, 0));
        setTableProperty_args args = new setTableProperty_args();
        args.setLogin(login);
        args.setTableName(tableName);
        args.setProperty(property);
        args.setValue(value);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public Void getResult() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          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 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<java.util.Set<Range>> {
      private java.nio.ByteBuffer login;
      private java.lang.String tableName;
      private Range range;
      private int maxSplits;
      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;
        this.range = range;
        this.maxSplits = maxSplits;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("splitRangeByTablets", org.apache.thrift.protocol.TMessageType.CALL, 0));
        splitRangeByTablets_args args = new splitRangeByTablets_args();
        args.setLogin(login);
        args.setTableName(tableName);
        args.setRange(range);
        args.setMaxSplits(maxSplits);
        args.write(prot);
        prot.writeMessageEnd();
      }

      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 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 (new Client(prot)).recv_splitRangeByTablets();
      }
    }

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

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("tableExists", org.apache.thrift.protocol.TMessageType.CALL, 0));
        tableExists_args args = new tableExists_args();
        args.setLogin(login);
        args.setTableName(tableName);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public java.lang.Boolean getResult() throws org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          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 (new Client(prot)).recv_tableExists();
      }
    }

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

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("tableIdMap", org.apache.thrift.protocol.TMessageType.CALL, 0));
        tableIdMap_args args = new tableIdMap_args();
        args.setLogin(login);
        args.write(prot);
        prot.writeMessageEnd();
      }

      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 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 (new Client(prot)).recv_tableIdMap();
      }
    }

    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<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;
        this.className = className;
        this.asTypeName = asTypeName;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("testTableClassLoad", org.apache.thrift.protocol.TMessageType.CALL, 0));
        testTableClassLoad_args args = new testTableClassLoad_args();
        args.setLogin(login);
        args.setTableName(tableName);
        args.setClassName(className);
        args.setAsTypeName(asTypeName);
        args.write(prot);
        prot.writeMessageEnd();
      }

      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 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 (new Client(prot)).recv_testTableClassLoad();
      }
    }

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

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("pingTabletServer", org.apache.thrift.protocol.TMessageType.CALL, 0));
        pingTabletServer_args args = new pingTabletServer_args();
        args.setLogin(login);
        args.setTserver(tserver);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public Void getResult() throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new 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 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<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;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("getActiveScans", org.apache.thrift.protocol.TMessageType.CALL, 0));
        getActiveScans_args args = new getActiveScans_args();
        args.setLogin(login);
        args.setTserver(tserver);
        args.write(prot);
        prot.writeMessageEnd();
      }

      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 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 (new Client(prot)).recv_getActiveScans();
      }
    }

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

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("getActiveCompactions", org.apache.thrift.protocol.TMessageType.CALL, 0));
        getActiveCompactions_args args = new getActiveCompactions_args();
        args.setLogin(login);
        args.setTserver(tserver);
        args.write(prot);
        prot.writeMessageEnd();
      }

      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 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 (new Client(prot)).recv_getActiveCompactions();
      }
    }

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

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("getSiteConfiguration", org.apache.thrift.protocol.TMessageType.CALL, 0));
        getSiteConfiguration_args args = new getSiteConfiguration_args();
        args.setLogin(login);
        args.write(prot);
        prot.writeMessageEnd();
      }

      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 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 (new Client(prot)).recv_getSiteConfiguration();
      }
    }

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

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("getSystemConfiguration", org.apache.thrift.protocol.TMessageType.CALL, 0));
        getSystemConfiguration_args args = new getSystemConfiguration_args();
        args.setLogin(login);
        args.write(prot);
        prot.writeMessageEnd();
      }

      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 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 (new Client(prot)).recv_getSystemConfiguration();
      }
    }

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

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("getTabletServers", org.apache.thrift.protocol.TMessageType.CALL, 0));
        getTabletServers_args args = new getTabletServers_args();
        args.setLogin(login);
        args.write(prot);
        prot.writeMessageEnd();
      }

      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 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 (new Client(prot)).recv_getTabletServers();
      }
    }

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

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("removeProperty", org.apache.thrift.protocol.TMessageType.CALL, 0));
        removeProperty_args args = new removeProperty_args();
        args.setLogin(login);
        args.setProperty(property);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public Void getResult() throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new 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 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<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;
        this.value = value;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("setProperty", org.apache.thrift.protocol.TMessageType.CALL, 0));
        setProperty_args args = new setProperty_args();
        args.setLogin(login);
        args.setProperty(property);
        args.setValue(value);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public Void getResult() throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new 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 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<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;
        this.asTypeName = asTypeName;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("testClassLoad", org.apache.thrift.protocol.TMessageType.CALL, 0));
        testClassLoad_args args = new testClassLoad_args();
        args.setLogin(login);
        args.setClassName(className);
        args.setAsTypeName(asTypeName);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public java.lang.Boolean getResult() throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          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 (new Client(prot)).recv_testClassLoad();
      }
    }

    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<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;
        this.properties = properties;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("authenticateUser", org.apache.thrift.protocol.TMessageType.CALL, 0));
        authenticateUser_args args = new authenticateUser_args();
        args.setLogin(login);
        args.setUser(user);
        args.setProperties(properties);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public java.lang.Boolean getResult() throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          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 (new Client(prot)).recv_authenticateUser();
      }
    }

    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<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;
        this.authorizations = authorizations;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("changeUserAuthorizations", org.apache.thrift.protocol.TMessageType.CALL, 0));
        changeUserAuthorizations_args args = new changeUserAuthorizations_args();
        args.setLogin(login);
        args.setUser(user);
        args.setAuthorizations(authorizations);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public Void getResult() throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new 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 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<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;
        this.password = password;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("changeLocalUserPassword", org.apache.thrift.protocol.TMessageType.CALL, 0));
        changeLocalUserPassword_args args = new changeLocalUserPassword_args();
        args.setLogin(login);
        args.setUser(user);
        args.setPassword(password);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public Void getResult() throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new 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 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<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;
        this.password = password;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("createLocalUser", org.apache.thrift.protocol.TMessageType.CALL, 0));
        createLocalUser_args args = new createLocalUser_args();
        args.setLogin(login);
        args.setUser(user);
        args.setPassword(password);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public Void getResult() throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new 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 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<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;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("dropLocalUser", org.apache.thrift.protocol.TMessageType.CALL, 0));
        dropLocalUser_args args = new dropLocalUser_args();
        args.setLogin(login);
        args.setUser(user);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public Void getResult() throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new 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 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<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;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("getUserAuthorizations", org.apache.thrift.protocol.TMessageType.CALL, 0));
        getUserAuthorizations_args args = new getUserAuthorizations_args();
        args.setLogin(login);
        args.setUser(user);
        args.write(prot);
        prot.writeMessageEnd();
      }

      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 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 (new Client(prot)).recv_getUserAuthorizations();
      }
    }

    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<Void> {
      private java.nio.ByteBuffer login;
      private java.lang.String user;
      private SystemPermission perm;
      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;
        this.perm = perm;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("grantSystemPermission", org.apache.thrift.protocol.TMessageType.CALL, 0));
        grantSystemPermission_args args = new grantSystemPermission_args();
        args.setLogin(login);
        args.setUser(user);
        args.setPerm(perm);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public Void getResult() throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new 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 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<Void> {
      private java.nio.ByteBuffer login;
      private java.lang.String user;
      private java.lang.String table;
      private TablePermission perm;
      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;
        this.table = table;
        this.perm = perm;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("grantTablePermission", org.apache.thrift.protocol.TMessageType.CALL, 0));
        grantTablePermission_args args = new grantTablePermission_args();
        args.setLogin(login);
        args.setUser(user);
        args.setTable(table);
        args.setPerm(perm);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public Void getResult() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          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 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<java.lang.Boolean> {
      private java.nio.ByteBuffer login;
      private java.lang.String user;
      private SystemPermission perm;
      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;
        this.perm = perm;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("hasSystemPermission", org.apache.thrift.protocol.TMessageType.CALL, 0));
        hasSystemPermission_args args = new hasSystemPermission_args();
        args.setLogin(login);
        args.setUser(user);
        args.setPerm(perm);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public java.lang.Boolean getResult() throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          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 (new Client(prot)).recv_hasSystemPermission();
      }
    }

    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<java.lang.Boolean> {
      private java.nio.ByteBuffer login;
      private java.lang.String user;
      private java.lang.String table;
      private TablePermission perm;
      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;
        this.table = table;
        this.perm = perm;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("hasTablePermission", org.apache.thrift.protocol.TMessageType.CALL, 0));
        hasTablePermission_args args = new hasTablePermission_args();
        args.setLogin(login);
        args.setUser(user);
        args.setTable(table);
        args.setPerm(perm);
        args.write(prot);
        prot.writeMessageEnd();
      }

      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 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 (new Client(prot)).recv_hasTablePermission();
      }
    }

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

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("listLocalUsers", org.apache.thrift.protocol.TMessageType.CALL, 0));
        listLocalUsers_args args = new listLocalUsers_args();
        args.setLogin(login);
        args.write(prot);
        prot.writeMessageEnd();
      }

      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 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 (new Client(prot)).recv_listLocalUsers();
      }
    }

    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<Void> {
      private java.nio.ByteBuffer login;
      private java.lang.String user;
      private SystemPermission perm;
      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;
        this.perm = perm;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("revokeSystemPermission", org.apache.thrift.protocol.TMessageType.CALL, 0));
        revokeSystemPermission_args args = new revokeSystemPermission_args();
        args.setLogin(login);
        args.setUser(user);
        args.setPerm(perm);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public Void getResult() throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new 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 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<Void> {
      private java.nio.ByteBuffer login;
      private java.lang.String user;
      private java.lang.String table;
      private TablePermission perm;
      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;
        this.table = table;
        this.perm = perm;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("revokeTablePermission", org.apache.thrift.protocol.TMessageType.CALL, 0));
        revokeTablePermission_args args = new revokeTablePermission_args();
        args.setLogin(login);
        args.setUser(user);
        args.setTable(table);
        args.setPerm(perm);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public Void getResult() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          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 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<Void> {
      private java.nio.ByteBuffer login;
      private java.lang.String user;
      private java.lang.String namespaceName;
      private NamespacePermission perm;
      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;
        this.namespaceName = namespaceName;
        this.perm = perm;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("grantNamespacePermission", org.apache.thrift.protocol.TMessageType.CALL, 0));
        grantNamespacePermission_args args = new grantNamespacePermission_args();
        args.setLogin(login);
        args.setUser(user);
        args.setNamespaceName(namespaceName);
        args.setPerm(perm);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public Void getResult() throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new 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 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<java.lang.Boolean> {
      private java.nio.ByteBuffer login;
      private java.lang.String user;
      private java.lang.String namespaceName;
      private NamespacePermission perm;
      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;
        this.namespaceName = namespaceName;
        this.perm = perm;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("hasNamespacePermission", org.apache.thrift.protocol.TMessageType.CALL, 0));
        hasNamespacePermission_args args = new hasNamespacePermission_args();
        args.setLogin(login);
        args.setUser(user);
        args.setNamespaceName(namespaceName);
        args.setPerm(perm);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public java.lang.Boolean getResult() throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          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 (new Client(prot)).recv_hasNamespacePermission();
      }
    }

    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<Void> {
      private java.nio.ByteBuffer login;
      private java.lang.String user;
      private java.lang.String namespaceName;
      private NamespacePermission perm;
      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;
        this.namespaceName = namespaceName;
        this.perm = perm;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("revokeNamespacePermission", org.apache.thrift.protocol.TMessageType.CALL, 0));
        revokeNamespacePermission_args args = new revokeNamespacePermission_args();
        args.setLogin(login);
        args.setUser(user);
        args.setNamespaceName(namespaceName);
        args.setPerm(perm);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public Void getResult() throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new 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 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<java.lang.String> {
      private java.nio.ByteBuffer login;
      private java.lang.String tableName;
      private BatchScanOptions options;
      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;
        this.options = options;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("createBatchScanner", org.apache.thrift.protocol.TMessageType.CALL, 0));
        createBatchScanner_args args = new createBatchScanner_args();
        args.setLogin(login);
        args.setTableName(tableName);
        args.setOptions(options);
        args.write(prot);
        prot.writeMessageEnd();
      }

      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 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 (new Client(prot)).recv_createBatchScanner();
      }
    }

    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<java.lang.String> {
      private java.nio.ByteBuffer login;
      private java.lang.String tableName;
      private ScanOptions options;
      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;
        this.options = options;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("createScanner", org.apache.thrift.protocol.TMessageType.CALL, 0));
        createScanner_args args = new createScanner_args();
        args.setLogin(login);
        args.setTableName(tableName);
        args.setOptions(options);
        args.write(prot);
        prot.writeMessageEnd();
      }

      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 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 (new Client(prot)).recv_createScanner();
      }
    }

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

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("hasNext", org.apache.thrift.protocol.TMessageType.CALL, 0));
        hasNext_args args = new hasNext_args();
        args.setScanner(scanner);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public java.lang.Boolean getResult() throws UnknownScanner, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          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 (new Client(prot)).recv_hasNext();
      }
    }

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

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("nextEntry", org.apache.thrift.protocol.TMessageType.CALL, 0));
        nextEntry_args args = new nextEntry_args();
        args.setScanner(scanner);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public KeyValueAndPeek getResult() throws NoMoreEntriesException, UnknownScanner, AccumuloSecurityException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          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 (new Client(prot)).recv_nextEntry();
      }
    }

    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<ScanResult> {
      private java.lang.String scanner;
      private int k;
      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;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("nextK", org.apache.thrift.protocol.TMessageType.CALL, 0));
        nextK_args args = new nextK_args();
        args.setScanner(scanner);
        args.setK(k);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public ScanResult getResult() throws NoMoreEntriesException, UnknownScanner, AccumuloSecurityException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          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 (new Client(prot)).recv_nextK();
      }
    }

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

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("closeScanner", org.apache.thrift.protocol.TMessageType.CALL, 0));
        closeScanner_args args = new closeScanner_args();
        args.setScanner(scanner);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public Void getResult() throws UnknownScanner, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          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 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<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;
        this.cells = cells;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("updateAndFlush", org.apache.thrift.protocol.TMessageType.CALL, 0));
        updateAndFlush_args args = new updateAndFlush_args();
        args.setLogin(login);
        args.setTableName(tableName);
        args.setCells(cells);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public Void getResult() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, MutationsRejectedException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          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 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<java.lang.String> {
      private java.nio.ByteBuffer login;
      private java.lang.String tableName;
      private WriterOptions opts;
      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;
        this.opts = opts;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("createWriter", org.apache.thrift.protocol.TMessageType.CALL, 0));
        createWriter_args args = new createWriter_args();
        args.setLogin(login);
        args.setTableName(tableName);
        args.setOpts(opts);
        args.write(prot);
        prot.writeMessageEnd();
      }

      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 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 (new Client(prot)).recv_createWriter();
      }
    }

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

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("update", org.apache.thrift.protocol.TMessageType.ONEWAY, 0));
        update_args args = new update_args();
        args.setWriter(writer);
        args.setCells(cells);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public Void getResult() throws org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          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(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<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;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("flush", org.apache.thrift.protocol.TMessageType.CALL, 0));
        flush_args args = new flush_args();
        args.setWriter(writer);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public Void getResult() throws UnknownWriter, MutationsRejectedException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          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 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<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;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("closeWriter", org.apache.thrift.protocol.TMessageType.CALL, 0));
        closeWriter_args args = new closeWriter_args();
        args.setWriter(writer);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public Void getResult() throws UnknownWriter, MutationsRejectedException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          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 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<ConditionalStatus> {
      private java.nio.ByteBuffer login;
      private java.lang.String tableName;
      private java.nio.ByteBuffer row;
      private ConditionalUpdates updates;
      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;
        this.row = row;
        this.updates = updates;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("updateRowConditionally", org.apache.thrift.protocol.TMessageType.CALL, 0));
        updateRowConditionally_args args = new updateRowConditionally_args();
        args.setLogin(login);
        args.setTableName(tableName);
        args.setRow(row);
        args.setUpdates(updates);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public ConditionalStatus getResult() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          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 (new Client(prot)).recv_updateRowConditionally();
      }
    }

    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<java.lang.String> {
      private java.nio.ByteBuffer login;
      private java.lang.String tableName;
      private ConditionalWriterOptions options;
      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;
        this.options = options;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("createConditionalWriter", org.apache.thrift.protocol.TMessageType.CALL, 0));
        createConditionalWriter_args args = new createConditionalWriter_args();
        args.setLogin(login);
        args.setTableName(tableName);
        args.setOptions(options);
        args.write(prot);
        prot.writeMessageEnd();
      }

      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 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 (new Client(prot)).recv_createConditionalWriter();
      }
    }

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

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("updateRowsConditionally", org.apache.thrift.protocol.TMessageType.CALL, 0));
        updateRowsConditionally_args args = new updateRowsConditionally_args();
        args.setConditionalWriter(conditionalWriter);
        args.setUpdates(updates);
        args.write(prot);
        prot.writeMessageEnd();
      }

      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 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 (new Client(prot)).recv_updateRowsConditionally();
      }
    }

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

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("closeConditionalWriter", org.apache.thrift.protocol.TMessageType.CALL, 0));
        closeConditionalWriter_args args = new closeConditionalWriter_args();
        args.setConditionalWriter(conditionalWriter);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public Void getResult() throws org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          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 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<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;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("getRowRange", org.apache.thrift.protocol.TMessageType.CALL, 0));
        getRowRange_args args = new getRowRange_args();
        args.setRow(row);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public Range getResult() throws org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          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 (new Client(prot)).recv_getRowRange();
      }
    }

    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<Key> {
      private Key key;
      private PartialKey part;
      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;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("getFollowing", org.apache.thrift.protocol.TMessageType.CALL, 0));
        getFollowing_args args = new getFollowing_args();
        args.setKey(key);
        args.setPart(part);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public Key getResult() throws org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          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 (new Client(prot)).recv_getFollowing();
      }
    }

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

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("systemNamespace", org.apache.thrift.protocol.TMessageType.CALL, 0));
        systemNamespace_args args = new systemNamespace_args();
        args.write(prot);
        prot.writeMessageEnd();
      }

      public java.lang.String getResult() throws org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          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 (new Client(prot)).recv_systemNamespace();
      }
    }

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

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("defaultNamespace", org.apache.thrift.protocol.TMessageType.CALL, 0));
        defaultNamespace_args args = new defaultNamespace_args();
        args.write(prot);
        prot.writeMessageEnd();
      }

      public java.lang.String getResult() throws org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          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 (new Client(prot)).recv_defaultNamespace();
      }
    }

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

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("listNamespaces", org.apache.thrift.protocol.TMessageType.CALL, 0));
        listNamespaces_args args = new listNamespaces_args();
        args.setLogin(login);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public 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 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 (new Client(prot)).recv_listNamespaces();
      }
    }

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

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("namespaceExists", org.apache.thrift.protocol.TMessageType.CALL, 0));
        namespaceExists_args args = new namespaceExists_args();
        args.setLogin(login);
        args.setNamespaceName(namespaceName);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public java.lang.Boolean getResult() throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          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 (new Client(prot)).recv_namespaceExists();
      }
    }

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

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("createNamespace", org.apache.thrift.protocol.TMessageType.CALL, 0));
        createNamespace_args args = new createNamespace_args();
        args.setLogin(login);
        args.setNamespaceName(namespaceName);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public Void getResult() throws AccumuloException, AccumuloSecurityException, NamespaceExistsException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new 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 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<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;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("deleteNamespace", org.apache.thrift.protocol.TMessageType.CALL, 0));
        deleteNamespace_args args = new deleteNamespace_args();
        args.setLogin(login);
        args.setNamespaceName(namespaceName);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public Void getResult() throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, NamespaceNotEmptyException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new 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 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<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;
        this.newNamespaceName = newNamespaceName;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("renameNamespace", org.apache.thrift.protocol.TMessageType.CALL, 0));
        renameNamespace_args args = new renameNamespace_args();
        args.setLogin(login);
        args.setOldNamespaceName(oldNamespaceName);
        args.setNewNamespaceName(newNamespaceName);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public Void getResult() throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, NamespaceExistsException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new 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 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<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;
        this.property = property;
        this.value = value;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("setNamespaceProperty", org.apache.thrift.protocol.TMessageType.CALL, 0));
        setNamespaceProperty_args args = new setNamespaceProperty_args();
        args.setLogin(login);
        args.setNamespaceName(namespaceName);
        args.setProperty(property);
        args.setValue(value);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public Void getResult() throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new 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 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<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;
        this.property = property;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("removeNamespaceProperty", org.apache.thrift.protocol.TMessageType.CALL, 0));
        removeNamespaceProperty_args args = new removeNamespaceProperty_args();
        args.setLogin(login);
        args.setNamespaceName(namespaceName);
        args.setProperty(property);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public Void getResult() throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new 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 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<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;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("getNamespaceProperties", org.apache.thrift.protocol.TMessageType.CALL, 0));
        getNamespaceProperties_args args = new getNamespaceProperties_args();
        args.setLogin(login);
        args.setNamespaceName(namespaceName);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public 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 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 (new Client(prot)).recv_getNamespaceProperties();
      }
    }

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

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("namespaceIdMap", org.apache.thrift.protocol.TMessageType.CALL, 0));
        namespaceIdMap_args args = new namespaceIdMap_args();
        args.setLogin(login);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public 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 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 (new Client(prot)).recv_namespaceIdMap();
      }
    }

    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<Void> {
      private java.nio.ByteBuffer login;
      private java.lang.String namespaceName;
      private IteratorSetting setting;
      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;
        this.setting = setting;
        this.scopes = scopes;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("attachNamespaceIterator", org.apache.thrift.protocol.TMessageType.CALL, 0));
        attachNamespaceIterator_args args = new attachNamespaceIterator_args();
        args.setLogin(login);
        args.setNamespaceName(namespaceName);
        args.setSetting(setting);
        args.setScopes(scopes);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public Void getResult() throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new 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 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<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;
        this.name = name;
        this.scopes = scopes;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("removeNamespaceIterator", org.apache.thrift.protocol.TMessageType.CALL, 0));
        removeNamespaceIterator_args args = new removeNamespaceIterator_args();
        args.setLogin(login);
        args.setNamespaceName(namespaceName);
        args.setName(name);
        args.setScopes(scopes);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public Void getResult() throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new 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 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<IteratorSetting> {
      private java.nio.ByteBuffer login;
      private java.lang.String namespaceName;
      private java.lang.String name;
      private IteratorScope scope;
      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;
        this.name = name;
        this.scope = scope;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("getNamespaceIteratorSetting", org.apache.thrift.protocol.TMessageType.CALL, 0));
        getNamespaceIteratorSetting_args args = new getNamespaceIteratorSetting_args();
        args.setLogin(login);
        args.setNamespaceName(namespaceName);
        args.setName(name);
        args.setScope(scope);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public IteratorSetting getResult() throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new 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 (new Client(prot)).recv_getNamespaceIteratorSetting();
      }
    }

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

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("listNamespaceIterators", org.apache.thrift.protocol.TMessageType.CALL, 0));
        listNamespaceIterators_args args = new listNamespaceIterators_args();
        args.setLogin(login);
        args.setNamespaceName(namespaceName);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public 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 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 (new Client(prot)).recv_listNamespaceIterators();
      }
    }

    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<Void> {
      private java.nio.ByteBuffer login;
      private java.lang.String namespaceName;
      private IteratorSetting setting;
      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;
        this.setting = setting;
        this.scopes = scopes;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("checkNamespaceIteratorConflicts", org.apache.thrift.protocol.TMessageType.CALL, 0));
        checkNamespaceIteratorConflicts_args args = new checkNamespaceIteratorConflicts_args();
        args.setLogin(login);
        args.setNamespaceName(namespaceName);
        args.setSetting(setting);
        args.setScopes(scopes);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public Void getResult() throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new 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 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<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;
        this.constraintClassName = constraintClassName;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("addNamespaceConstraint", org.apache.thrift.protocol.TMessageType.CALL, 0));
        addNamespaceConstraint_args args = new addNamespaceConstraint_args();
        args.setLogin(login);
        args.setNamespaceName(namespaceName);
        args.setConstraintClassName(constraintClassName);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public java.lang.Integer getResult() throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          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 (new Client(prot)).recv_addNamespaceConstraint();
      }
    }

    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<Void> {
      private java.nio.ByteBuffer login;
      private java.lang.String namespaceName;
      private int id;
      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;
        this.id = id;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("removeNamespaceConstraint", org.apache.thrift.protocol.TMessageType.CALL, 0));
        removeNamespaceConstraint_args args = new removeNamespaceConstraint_args();
        args.setLogin(login);
        args.setNamespaceName(namespaceName);
        args.setId(id);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public Void getResult() throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new 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 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<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;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("listNamespaceConstraints", org.apache.thrift.protocol.TMessageType.CALL, 0));
        listNamespaceConstraints_args args = new listNamespaceConstraints_args();
        args.setLogin(login);
        args.setNamespaceName(namespaceName);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public 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 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 (new Client(prot)).recv_listNamespaceConstraints();
      }
    }

    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<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;
        this.className = className;
        this.asTypeName = asTypeName;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("testNamespaceClassLoad", org.apache.thrift.protocol.TMessageType.CALL, 0));
        testNamespaceClassLoad_args args = new testNamespaceClassLoad_args();
        args.setLogin(login);
        args.setNamespaceName(namespaceName);
        args.setClassName(className);
        args.setAsTypeName(asTypeName);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public java.lang.Boolean getResult() throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          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 (new Client(prot)).recv_testNamespaceClassLoad();
      }
    }

  }

  public static class Processor<I extends Iface> extends org.apache.thrift.TBaseProcessor<I> implements org.apache.thrift.TProcessor {
    private static final org.slf4j.Logger _LOGGER = org.slf4j.LoggerFactory.getLogger(Processor.class.getName());
    public Processor(I iface) {
      super(iface, getProcessMap(new java.util.HashMap<java.lang.String, org.apache.thrift.ProcessFunction<I, ? extends org.apache.thrift.TBase>>()));
    }

    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> 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());
      processMap.put("attachIterator", new attachIterator());
      processMap.put("checkIteratorConflicts", new checkIteratorConflicts());
      processMap.put("clearLocatorCache", new clearLocatorCache());
      processMap.put("cloneTable", new cloneTable());
      processMap.put("compactTable", new compactTable());
      processMap.put("cancelCompaction", new cancelCompaction());
      processMap.put("createTable", new createTable());
      processMap.put("deleteTable", new deleteTable());
      processMap.put("deleteRows", new deleteRows());
      processMap.put("exportTable", new exportTable());
      processMap.put("flushTable", new flushTable());
      processMap.put("getDiskUsage", new getDiskUsage());
      processMap.put("getLocalityGroups", new getLocalityGroups());
      processMap.put("getIteratorSetting", new getIteratorSetting());
      processMap.put("getMaxRow", new getMaxRow());
      processMap.put("getTableProperties", new getTableProperties());
      processMap.put("importDirectory", new importDirectory());
      processMap.put("importTable", new importTable());
      processMap.put("listSplits", new listSplits());
      processMap.put("listTables", new listTables());
      processMap.put("listIterators", new listIterators());
      processMap.put("listConstraints", new listConstraints());
      processMap.put("mergeTablets", new mergeTablets());
      processMap.put("offlineTable", new offlineTable());
      processMap.put("onlineTable", new onlineTable());
      processMap.put("removeConstraint", new removeConstraint());
      processMap.put("removeIterator", new removeIterator());
      processMap.put("removeTableProperty", new removeTableProperty());
      processMap.put("renameTable", new renameTable());
      processMap.put("setLocalityGroups", new setLocalityGroups());
      processMap.put("setTableProperty", new setTableProperty());
      processMap.put("splitRangeByTablets", new splitRangeByTablets());
      processMap.put("tableExists", new tableExists());
      processMap.put("tableIdMap", new tableIdMap());
      processMap.put("testTableClassLoad", new testTableClassLoad());
      processMap.put("pingTabletServer", new pingTabletServer());
      processMap.put("getActiveScans", new getActiveScans());
      processMap.put("getActiveCompactions", new getActiveCompactions());
      processMap.put("getSiteConfiguration", new getSiteConfiguration());
      processMap.put("getSystemConfiguration", new getSystemConfiguration());
      processMap.put("getTabletServers", new getTabletServers());
      processMap.put("removeProperty", new removeProperty());
      processMap.put("setProperty", new setProperty());
      processMap.put("testClassLoad", new testClassLoad());
      processMap.put("authenticateUser", new authenticateUser());
      processMap.put("changeUserAuthorizations", new changeUserAuthorizations());
      processMap.put("changeLocalUserPassword", new changeLocalUserPassword());
      processMap.put("createLocalUser", new createLocalUser());
      processMap.put("dropLocalUser", new dropLocalUser());
      processMap.put("getUserAuthorizations", new getUserAuthorizations());
      processMap.put("grantSystemPermission", new grantSystemPermission());
      processMap.put("grantTablePermission", new grantTablePermission());
      processMap.put("hasSystemPermission", new hasSystemPermission());
      processMap.put("hasTablePermission", new hasTablePermission());
      processMap.put("listLocalUsers", new listLocalUsers());
      processMap.put("revokeSystemPermission", new revokeSystemPermission());
      processMap.put("revokeTablePermission", new revokeTablePermission());
      processMap.put("grantNamespacePermission", new grantNamespacePermission());
      processMap.put("hasNamespacePermission", new hasNamespacePermission());
      processMap.put("revokeNamespacePermission", new revokeNamespacePermission());
      processMap.put("createBatchScanner", new createBatchScanner());
      processMap.put("createScanner", new createScanner());
      processMap.put("hasNext", new hasNext());
      processMap.put("nextEntry", new nextEntry());
      processMap.put("nextK", new nextK());
      processMap.put("closeScanner", new closeScanner());
      processMap.put("updateAndFlush", new updateAndFlush());
      processMap.put("createWriter", new createWriter());
      processMap.put("update", new update());
      processMap.put("flush", new flush());
      processMap.put("closeWriter", new closeWriter());
      processMap.put("updateRowConditionally", new updateRowConditionally());
      processMap.put("createConditionalWriter", new createConditionalWriter());
      processMap.put("updateRowsConditionally", new updateRowsConditionally());
      processMap.put("closeConditionalWriter", new closeConditionalWriter());
      processMap.put("getRowRange", new getRowRange());
      processMap.put("getFollowing", new getFollowing());
      processMap.put("systemNamespace", new systemNamespace());
      processMap.put("defaultNamespace", new defaultNamespace());
      processMap.put("listNamespaces", new listNamespaces());
      processMap.put("namespaceExists", new namespaceExists());
      processMap.put("createNamespace", new createNamespace());
      processMap.put("deleteNamespace", new deleteNamespace());
      processMap.put("renameNamespace", new renameNamespace());
      processMap.put("setNamespaceProperty", new setNamespaceProperty());
      processMap.put("removeNamespaceProperty", new removeNamespaceProperty());
      processMap.put("getNamespaceProperties", new getNamespaceProperties());
      processMap.put("namespaceIdMap", new namespaceIdMap());
      processMap.put("attachNamespaceIterator", new attachNamespaceIterator());
      processMap.put("removeNamespaceIterator", new removeNamespaceIterator());
      processMap.put("getNamespaceIteratorSetting", new getNamespaceIteratorSetting());
      processMap.put("listNamespaceIterators", new listNamespaceIterators());
      processMap.put("checkNamespaceIteratorConflicts", new checkNamespaceIteratorConflicts());
      processMap.put("addNamespaceConstraint", new addNamespaceConstraint());
      processMap.put("removeNamespaceConstraint", new removeNamespaceConstraint());
      processMap.put("listNamespaceConstraints", new listNamespaceConstraints());
      processMap.put("testNamespaceClassLoad", new testNamespaceClassLoad());
      return processMap;
    }

    public static class login<I extends Iface> extends org.apache.thrift.ProcessFunction<I, login_args> {
      public login() {
        super("login");
      }

      public login_args getEmptyArgsInstance() {
        return new login_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public login_result getResult(I iface, login_args args) throws org.apache.thrift.TException {
        login_result result = new login_result();
        try {
          result.success = iface.login(args.principal, args.loginProperties);
        } catch (AccumuloSecurityException ouch2) {
          result.ouch2 = ouch2;
        }
        return result;
      }
    }

    public static class addConstraint<I extends Iface> extends org.apache.thrift.ProcessFunction<I, addConstraint_args> {
      public addConstraint() {
        super("addConstraint");
      }

      public addConstraint_args getEmptyArgsInstance() {
        return new addConstraint_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public addConstraint_result getResult(I iface, addConstraint_args args) throws org.apache.thrift.TException {
        addConstraint_result result = new addConstraint_result();
        try {
          result.success = iface.addConstraint(args.login, args.tableName, args.constraintClassName);
          result.setSuccessIsSet(true);
        } catch (AccumuloException ouch1) {
          result.ouch1 = ouch1;
        } catch (AccumuloSecurityException ouch2) {
          result.ouch2 = ouch2;
        } catch (TableNotFoundException ouch3) {
          result.ouch3 = ouch3;
        }
        return result;
      }
    }

    public static class addSplits<I extends Iface> extends org.apache.thrift.ProcessFunction<I, addSplits_args> {
      public addSplits() {
        super("addSplits");
      }

      public addSplits_args getEmptyArgsInstance() {
        return new addSplits_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public addSplits_result getResult(I iface, addSplits_args args) throws org.apache.thrift.TException {
        addSplits_result result = new addSplits_result();
        try {
          iface.addSplits(args.login, args.tableName, args.splits);
        } catch (AccumuloException ouch1) {
          result.ouch1 = ouch1;
        } catch (AccumuloSecurityException ouch2) {
          result.ouch2 = ouch2;
        } catch (TableNotFoundException ouch3) {
          result.ouch3 = ouch3;
        }
        return result;
      }
    }

    public static class attachIterator<I extends Iface> extends org.apache.thrift.ProcessFunction<I, attachIterator_args> {
      public attachIterator() {
        super("attachIterator");
      }

      public attachIterator_args getEmptyArgsInstance() {
        return new attachIterator_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public attachIterator_result getResult(I iface, attachIterator_args args) throws org.apache.thrift.TException {
        attachIterator_result result = new attachIterator_result();
        try {
          iface.attachIterator(args.login, args.tableName, args.setting, args.scopes);
        } catch (AccumuloSecurityException ouch1) {
          result.ouch1 = ouch1;
        } catch (AccumuloException ouch2) {
          result.ouch2 = ouch2;
        } catch (TableNotFoundException ouch3) {
          result.ouch3 = ouch3;
        }
        return result;
      }
    }

    public static class checkIteratorConflicts<I extends Iface> extends org.apache.thrift.ProcessFunction<I, checkIteratorConflicts_args> {
      public checkIteratorConflicts() {
        super("checkIteratorConflicts");
      }

      public checkIteratorConflicts_args getEmptyArgsInstance() {
        return new checkIteratorConflicts_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public checkIteratorConflicts_result getResult(I iface, checkIteratorConflicts_args args) throws org.apache.thrift.TException {
        checkIteratorConflicts_result result = new checkIteratorConflicts_result();
        try {
          iface.checkIteratorConflicts(args.login, args.tableName, args.setting, args.scopes);
        } catch (AccumuloSecurityException ouch1) {
          result.ouch1 = ouch1;
        } catch (AccumuloException ouch2) {
          result.ouch2 = ouch2;
        } catch (TableNotFoundException ouch3) {
          result.ouch3 = ouch3;
        }
        return result;
      }
    }

    public static class clearLocatorCache<I extends Iface> extends org.apache.thrift.ProcessFunction<I, clearLocatorCache_args> {
      public clearLocatorCache() {
        super("clearLocatorCache");
      }

      public clearLocatorCache_args getEmptyArgsInstance() {
        return new clearLocatorCache_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public clearLocatorCache_result getResult(I iface, clearLocatorCache_args args) throws org.apache.thrift.TException {
        clearLocatorCache_result result = new clearLocatorCache_result();
        try {
          iface.clearLocatorCache(args.login, args.tableName);
        } catch (TableNotFoundException ouch1) {
          result.ouch1 = ouch1;
        }
        return result;
      }
    }

    public static class cloneTable<I extends Iface> extends org.apache.thrift.ProcessFunction<I, cloneTable_args> {
      public cloneTable() {
        super("cloneTable");
      }

      public cloneTable_args getEmptyArgsInstance() {
        return new cloneTable_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public cloneTable_result getResult(I iface, cloneTable_args args) throws org.apache.thrift.TException {
        cloneTable_result result = new cloneTable_result();
        try {
          iface.cloneTable(args.login, args.tableName, args.newTableName, args.flush, args.propertiesToSet, args.propertiesToExclude);
        } catch (AccumuloException ouch1) {
          result.ouch1 = ouch1;
        } catch (AccumuloSecurityException ouch2) {
          result.ouch2 = ouch2;
        } catch (TableNotFoundException ouch3) {
          result.ouch3 = ouch3;
        } catch (TableExistsException ouch4) {
          result.ouch4 = ouch4;
        }
        return result;
      }
    }

    public static class compactTable<I extends Iface> extends org.apache.thrift.ProcessFunction<I, compactTable_args> {
      public compactTable() {
        super("compactTable");
      }

      public compactTable_args getEmptyArgsInstance() {
        return new compactTable_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public compactTable_result getResult(I iface, compactTable_args args) throws org.apache.thrift.TException {
        compactTable_result result = new compactTable_result();
        try {
          iface.compactTable(args.login, args.tableName, args.startRow, args.endRow, args.iterators, args.flush, args.wait, args.compactionStrategy);
        } catch (AccumuloSecurityException ouch1) {
          result.ouch1 = ouch1;
        } catch (TableNotFoundException ouch2) {
          result.ouch2 = ouch2;
        } catch (AccumuloException ouch3) {
          result.ouch3 = ouch3;
        }
        return result;
      }
    }

    public static class cancelCompaction<I extends Iface> extends org.apache.thrift.ProcessFunction<I, cancelCompaction_args> {
      public cancelCompaction() {
        super("cancelCompaction");
      }

      public cancelCompaction_args getEmptyArgsInstance() {
        return new cancelCompaction_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public cancelCompaction_result getResult(I iface, cancelCompaction_args args) throws org.apache.thrift.TException {
        cancelCompaction_result result = new cancelCompaction_result();
        try {
          iface.cancelCompaction(args.login, args.tableName);
        } catch (AccumuloSecurityException ouch1) {
          result.ouch1 = ouch1;
        } catch (TableNotFoundException ouch2) {
          result.ouch2 = ouch2;
        } catch (AccumuloException ouch3) {
          result.ouch3 = ouch3;
        }
        return result;
      }
    }

    public static class createTable<I extends Iface> extends org.apache.thrift.ProcessFunction<I, createTable_args> {
      public createTable() {
        super("createTable");
      }

      public createTable_args getEmptyArgsInstance() {
        return new createTable_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public createTable_result getResult(I iface, createTable_args args) throws org.apache.thrift.TException {
        createTable_result result = new createTable_result();
        try {
          iface.createTable(args.login, args.tableName, args.versioningIter, args.type);
        } catch (AccumuloException ouch1) {
          result.ouch1 = ouch1;
        } catch (AccumuloSecurityException ouch2) {
          result.ouch2 = ouch2;
        } catch (TableExistsException ouch3) {
          result.ouch3 = ouch3;
        }
        return result;
      }
    }

    public static class deleteTable<I extends Iface> extends org.apache.thrift.ProcessFunction<I, deleteTable_args> {
      public deleteTable() {
        super("deleteTable");
      }

      public deleteTable_args getEmptyArgsInstance() {
        return new deleteTable_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public deleteTable_result getResult(I iface, deleteTable_args args) throws org.apache.thrift.TException {
        deleteTable_result result = new deleteTable_result();
        try {
          iface.deleteTable(args.login, args.tableName);
        } catch (AccumuloException ouch1) {
          result.ouch1 = ouch1;
        } catch (AccumuloSecurityException ouch2) {
          result.ouch2 = ouch2;
        } catch (TableNotFoundException ouch3) {
          result.ouch3 = ouch3;
        }
        return result;
      }
    }

    public static class deleteRows<I extends Iface> extends org.apache.thrift.ProcessFunction<I, deleteRows_args> {
      public deleteRows() {
        super("deleteRows");
      }

      public deleteRows_args getEmptyArgsInstance() {
        return new deleteRows_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public deleteRows_result getResult(I iface, deleteRows_args args) throws org.apache.thrift.TException {
        deleteRows_result result = new deleteRows_result();
        try {
          iface.deleteRows(args.login, args.tableName, args.startRow, args.endRow);
        } catch (AccumuloException ouch1) {
          result.ouch1 = ouch1;
        } catch (AccumuloSecurityException ouch2) {
          result.ouch2 = ouch2;
        } catch (TableNotFoundException ouch3) {
          result.ouch3 = ouch3;
        }
        return result;
      }
    }

    public static class exportTable<I extends Iface> extends org.apache.thrift.ProcessFunction<I, exportTable_args> {
      public exportTable() {
        super("exportTable");
      }

      public exportTable_args getEmptyArgsInstance() {
        return new exportTable_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public exportTable_result getResult(I iface, exportTable_args args) throws org.apache.thrift.TException {
        exportTable_result result = new exportTable_result();
        try {
          iface.exportTable(args.login, args.tableName, args.exportDir);
        } catch (AccumuloException ouch1) {
          result.ouch1 = ouch1;
        } catch (AccumuloSecurityException ouch2) {
          result.ouch2 = ouch2;
        } catch (TableNotFoundException ouch3) {
          result.ouch3 = ouch3;
        }
        return result;
      }
    }

    public static class flushTable<I extends Iface> extends org.apache.thrift.ProcessFunction<I, flushTable_args> {
      public flushTable() {
        super("flushTable");
      }

      public flushTable_args getEmptyArgsInstance() {
        return new flushTable_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public flushTable_result getResult(I iface, flushTable_args args) throws org.apache.thrift.TException {
        flushTable_result result = new flushTable_result();
        try {
          iface.flushTable(args.login, args.tableName, args.startRow, args.endRow, args.wait);
        } catch (AccumuloException ouch1) {
          result.ouch1 = ouch1;
        } catch (AccumuloSecurityException ouch2) {
          result.ouch2 = ouch2;
        } catch (TableNotFoundException ouch3) {
          result.ouch3 = ouch3;
        }
        return result;
      }
    }

    public static class getDiskUsage<I extends Iface> extends org.apache.thrift.ProcessFunction<I, getDiskUsage_args> {
      public getDiskUsage() {
        super("getDiskUsage");
      }

      public getDiskUsage_args getEmptyArgsInstance() {
        return new getDiskUsage_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public getDiskUsage_result getResult(I iface, getDiskUsage_args args) throws org.apache.thrift.TException {
        getDiskUsage_result result = new getDiskUsage_result();
        try {
          result.success = iface.getDiskUsage(args.login, args.tables);
        } catch (AccumuloException ouch1) {
          result.ouch1 = ouch1;
        } catch (AccumuloSecurityException ouch2) {
          result.ouch2 = ouch2;
        } catch (TableNotFoundException ouch3) {
          result.ouch3 = ouch3;
        }
        return result;
      }
    }

    public static class getLocalityGroups<I extends Iface> extends org.apache.thrift.ProcessFunction<I, getLocalityGroups_args> {
      public getLocalityGroups() {
        super("getLocalityGroups");
      }

      public getLocalityGroups_args getEmptyArgsInstance() {
        return new getLocalityGroups_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public getLocalityGroups_result getResult(I iface, getLocalityGroups_args args) throws org.apache.thrift.TException {
        getLocalityGroups_result result = new getLocalityGroups_result();
        try {
          result.success = iface.getLocalityGroups(args.login, args.tableName);
        } catch (AccumuloException ouch1) {
          result.ouch1 = ouch1;
        } catch (AccumuloSecurityException ouch2) {
          result.ouch2 = ouch2;
        } catch (TableNotFoundException ouch3) {
          result.ouch3 = ouch3;
        }
        return result;
      }
    }

    public static class getIteratorSetting<I extends Iface> extends org.apache.thrift.ProcessFunction<I, getIteratorSetting_args> {
      public getIteratorSetting() {
        super("getIteratorSetting");
      }

      public getIteratorSetting_args getEmptyArgsInstance() {
        return new getIteratorSetting_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public getIteratorSetting_result getResult(I iface, getIteratorSetting_args args) throws org.apache.thrift.TException {
        getIteratorSetting_result result = new getIteratorSetting_result();
        try {
          result.success = iface.getIteratorSetting(args.login, args.tableName, args.iteratorName, args.scope);
        } catch (AccumuloException ouch1) {
          result.ouch1 = ouch1;
        } catch (AccumuloSecurityException ouch2) {
          result.ouch2 = ouch2;
        } catch (TableNotFoundException ouch3) {
          result.ouch3 = ouch3;
        }
        return result;
      }
    }

    public static class getMaxRow<I extends Iface> extends org.apache.thrift.ProcessFunction<I, getMaxRow_args> {
      public getMaxRow() {
        super("getMaxRow");
      }

      public getMaxRow_args getEmptyArgsInstance() {
        return new getMaxRow_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public getMaxRow_result getResult(I iface, getMaxRow_args args) throws org.apache.thrift.TException {
        getMaxRow_result result = new getMaxRow_result();
        try {
          result.success = iface.getMaxRow(args.login, args.tableName, args.auths, args.startRow, args.startInclusive, args.endRow, args.endInclusive);
        } catch (AccumuloException ouch1) {
          result.ouch1 = ouch1;
        } catch (AccumuloSecurityException ouch2) {
          result.ouch2 = ouch2;
        } catch (TableNotFoundException ouch3) {
          result.ouch3 = ouch3;
        }
        return result;
      }
    }

    public static class getTableProperties<I extends Iface> extends org.apache.thrift.ProcessFunction<I, getTableProperties_args> {
      public getTableProperties() {
        super("getTableProperties");
      }

      public getTableProperties_args getEmptyArgsInstance() {
        return new getTableProperties_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public getTableProperties_result getResult(I iface, getTableProperties_args args) throws org.apache.thrift.TException {
        getTableProperties_result result = new getTableProperties_result();
        try {
          result.success = iface.getTableProperties(args.login, args.tableName);
        } catch (AccumuloException ouch1) {
          result.ouch1 = ouch1;
        } catch (AccumuloSecurityException ouch2) {
          result.ouch2 = ouch2;
        } catch (TableNotFoundException ouch3) {
          result.ouch3 = ouch3;
        }
        return result;
      }
    }

    public static class importDirectory<I extends Iface> extends org.apache.thrift.ProcessFunction<I, importDirectory_args> {
      public importDirectory() {
        super("importDirectory");
      }

      public importDirectory_args getEmptyArgsInstance() {
        return new importDirectory_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public importDirectory_result getResult(I iface, importDirectory_args args) throws org.apache.thrift.TException {
        importDirectory_result result = new importDirectory_result();
        try {
          iface.importDirectory(args.login, args.tableName, args.importDir, args.failureDir, args.setTime);
        } catch (TableNotFoundException ouch1) {
          result.ouch1 = ouch1;
        } catch (AccumuloException ouch3) {
          result.ouch3 = ouch3;
        } catch (AccumuloSecurityException ouch4) {
          result.ouch4 = ouch4;
        }
        return result;
      }
    }

    public static class importTable<I extends Iface> extends org.apache.thrift.ProcessFunction<I, importTable_args> {
      public importTable() {
        super("importTable");
      }

      public importTable_args getEmptyArgsInstance() {
        return new importTable_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public importTable_result getResult(I iface, importTable_args args) throws org.apache.thrift.TException {
        importTable_result result = new importTable_result();
        try {
          iface.importTable(args.login, args.tableName, args.importDir);
        } catch (TableExistsException ouch1) {
          result.ouch1 = ouch1;
        } catch (AccumuloException ouch2) {
          result.ouch2 = ouch2;
        } catch (AccumuloSecurityException ouch3) {
          result.ouch3 = ouch3;
        }
        return result;
      }
    }

    public static class listSplits<I extends Iface> extends org.apache.thrift.ProcessFunction<I, listSplits_args> {
      public listSplits() {
        super("listSplits");
      }

      public listSplits_args getEmptyArgsInstance() {
        return new listSplits_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public listSplits_result getResult(I iface, listSplits_args args) throws org.apache.thrift.TException {
        listSplits_result result = new listSplits_result();
        try {
          result.success = iface.listSplits(args.login, args.tableName, args.maxSplits);
        } catch (AccumuloException ouch1) {
          result.ouch1 = ouch1;
        } catch (AccumuloSecurityException ouch2) {
          result.ouch2 = ouch2;
        } catch (TableNotFoundException ouch3) {
          result.ouch3 = ouch3;
        }
        return result;
      }
    }

    public static class listTables<I extends Iface> extends org.apache.thrift.ProcessFunction<I, listTables_args> {
      public listTables() {
        super("listTables");
      }

      public listTables_args getEmptyArgsInstance() {
        return new listTables_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public listTables_result getResult(I iface, listTables_args args) throws org.apache.thrift.TException {
        listTables_result result = new listTables_result();
        result.success = iface.listTables(args.login);
        return result;
      }
    }

    public static class listIterators<I extends Iface> extends org.apache.thrift.ProcessFunction<I, listIterators_args> {
      public listIterators() {
        super("listIterators");
      }

      public listIterators_args getEmptyArgsInstance() {
        return new listIterators_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public listIterators_result getResult(I iface, listIterators_args args) throws org.apache.thrift.TException {
        listIterators_result result = new listIterators_result();
        try {
          result.success = iface.listIterators(args.login, args.tableName);
        } catch (AccumuloException ouch1) {
          result.ouch1 = ouch1;
        } catch (AccumuloSecurityException ouch2) {
          result.ouch2 = ouch2;
        } catch (TableNotFoundException ouch3) {
          result.ouch3 = ouch3;
        }
        return result;
      }
    }

    public static class listConstraints<I extends Iface> extends org.apache.thrift.ProcessFunction<I, listConstraints_args> {
      public listConstraints() {
        super("listConstraints");
      }

      public listConstraints_args getEmptyArgsInstance() {
        return new listConstraints_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public listConstraints_result getResult(I iface, listConstraints_args args) throws org.apache.thrift.TException {
        listConstraints_result result = new listConstraints_result();
        try {
          result.success = iface.listConstraints(args.login, args.tableName);
        } catch (AccumuloException ouch1) {
          result.ouch1 = ouch1;
        } catch (AccumuloSecurityException ouch2) {
          result.ouch2 = ouch2;
        } catch (TableNotFoundException ouch3) {
          result.ouch3 = ouch3;
        }
        return result;
      }
    }

    public static class mergeTablets<I extends Iface> extends org.apache.thrift.ProcessFunction<I, mergeTablets_args> {
      public mergeTablets() {
        super("mergeTablets");
      }

      public mergeTablets_args getEmptyArgsInstance() {
        return new mergeTablets_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public mergeTablets_result getResult(I iface, mergeTablets_args args) throws org.apache.thrift.TException {
        mergeTablets_result result = new mergeTablets_result();
        try {
          iface.mergeTablets(args.login, args.tableName, args.startRow, args.endRow);
        } catch (AccumuloException ouch1) {
          result.ouch1 = ouch1;
        } catch (AccumuloSecurityException ouch2) {
          result.ouch2 = ouch2;
        } catch (TableNotFoundException ouch3) {
          result.ouch3 = ouch3;
        }
        return result;
      }
    }

    public static class offlineTable<I extends Iface> extends org.apache.thrift.ProcessFunction<I, offlineTable_args> {
      public offlineTable() {
        super("offlineTable");
      }

      public offlineTable_args getEmptyArgsInstance() {
        return new offlineTable_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public offlineTable_result getResult(I iface, offlineTable_args args) throws org.apache.thrift.TException {
        offlineTable_result result = new offlineTable_result();
        try {
          iface.offlineTable(args.login, args.tableName, args.wait);
        } catch (AccumuloException ouch1) {
          result.ouch1 = ouch1;
        } catch (AccumuloSecurityException ouch2) {
          result.ouch2 = ouch2;
        } catch (TableNotFoundException ouch3) {
          result.ouch3 = ouch3;
        }
        return result;
      }
    }

    public static class onlineTable<I extends Iface> extends org.apache.thrift.ProcessFunction<I, onlineTable_args> {
      public onlineTable() {
        super("onlineTable");
      }

      public onlineTable_args getEmptyArgsInstance() {
        return new onlineTable_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public onlineTable_result getResult(I iface, onlineTable_args args) throws org.apache.thrift.TException {
        onlineTable_result result = new onlineTable_result();
        try {
          iface.onlineTable(args.login, args.tableName, args.wait);
        } catch (AccumuloException ouch1) {
          result.ouch1 = ouch1;
        } catch (AccumuloSecurityException ouch2) {
          result.ouch2 = ouch2;
        } catch (TableNotFoundException ouch3) {
          result.ouch3 = ouch3;
        }
        return result;
      }
    }

    public static class removeConstraint<I extends Iface> extends org.apache.thrift.ProcessFunction<I, removeConstraint_args> {
      public removeConstraint() {
        super("removeConstraint");
      }

      public removeConstraint_args getEmptyArgsInstance() {
        return new removeConstraint_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public removeConstraint_result getResult(I iface, removeConstraint_args args) throws org.apache.thrift.TException {
        removeConstraint_result result = new removeConstraint_result();
        try {
          iface.removeConstraint(args.login, args.tableName, args.constraint);
        } catch (AccumuloException ouch1) {
          result.ouch1 = ouch1;
        } catch (AccumuloSecurityException ouch2) {
          result.ouch2 = ouch2;
        } catch (TableNotFoundException ouch3) {
          result.ouch3 = ouch3;
        }
        return result;
      }
    }

    public static class removeIterator<I extends Iface> extends org.apache.thrift.ProcessFunction<I, removeIterator_args> {
      public removeIterator() {
        super("removeIterator");
      }

      public removeIterator_args getEmptyArgsInstance() {
        return new removeIterator_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public removeIterator_result getResult(I iface, removeIterator_args args) throws org.apache.thrift.TException {
        removeIterator_result result = new removeIterator_result();
        try {
          iface.removeIterator(args.login, args.tableName, args.iterName, args.scopes);
        } catch (AccumuloException ouch1) {
          result.ouch1 = ouch1;
        } catch (AccumuloSecurityException ouch2) {
          result.ouch2 = ouch2;
        } catch (TableNotFoundException ouch3) {
          result.ouch3 = ouch3;
        }
        return result;
      }
    }

    public static class removeTableProperty<I extends Iface> extends org.apache.thrift.ProcessFunction<I, removeTableProperty_args> {
      public removeTableProperty() {
        super("removeTableProperty");
      }

      public removeTableProperty_args getEmptyArgsInstance() {
        return new removeTableProperty_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public removeTableProperty_result getResult(I iface, removeTableProperty_args args) throws org.apache.thrift.TException {
        removeTableProperty_result result = new removeTableProperty_result();
        try {
          iface.removeTableProperty(args.login, args.tableName, args.property);
        } catch (AccumuloException ouch1) {
          result.ouch1 = ouch1;
        } catch (AccumuloSecurityException ouch2) {
          result.ouch2 = ouch2;
        } catch (TableNotFoundException ouch3) {
          result.ouch3 = ouch3;
        }
        return result;
      }
    }

    public static class renameTable<I extends Iface> extends org.apache.thrift.ProcessFunction<I, renameTable_args> {
      public renameTable() {
        super("renameTable");
      }

      public renameTable_args getEmptyArgsInstance() {
        return new renameTable_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public renameTable_result getResult(I iface, renameTable_args args) throws org.apache.thrift.TException {
        renameTable_result result = new renameTable_result();
        try {
          iface.renameTable(args.login, args.oldTableName, args.newTableName);
        } catch (AccumuloException ouch1) {
          result.ouch1 = ouch1;
        } catch (AccumuloSecurityException ouch2) {
          result.ouch2 = ouch2;
        } catch (TableNotFoundException ouch3) {
          result.ouch3 = ouch3;
        } catch (TableExistsException ouch4) {
          result.ouch4 = ouch4;
        }
        return result;
      }
    }

    public static class setLocalityGroups<I extends Iface> extends org.apache.thrift.ProcessFunction<I, setLocalityGroups_args> {
      public setLocalityGroups() {
        super("setLocalityGroups");
      }

      public setLocalityGroups_args getEmptyArgsInstance() {
        return new setLocalityGroups_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public setLocalityGroups_result getResult(I iface, setLocalityGroups_args args) throws org.apache.thrift.TException {
        setLocalityGroups_result result = new setLocalityGroups_result();
        try {
          iface.setLocalityGroups(args.login, args.tableName, args.groups);
        } catch (AccumuloException ouch1) {
          result.ouch1 = ouch1;
        } catch (AccumuloSecurityException ouch2) {
          result.ouch2 = ouch2;
        } catch (TableNotFoundException ouch3) {
          result.ouch3 = ouch3;
        }
        return result;
      }
    }

    public static class setTableProperty<I extends Iface> extends org.apache.thrift.ProcessFunction<I, setTableProperty_args> {
      public setTableProperty() {
        super("setTableProperty");
      }

      public setTableProperty_args getEmptyArgsInstance() {
        return new setTableProperty_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public setTableProperty_result getResult(I iface, setTableProperty_args args) throws org.apache.thrift.TException {
        setTableProperty_result result = new setTableProperty_result();
        try {
          iface.setTableProperty(args.login, args.tableName, args.property, args.value);
        } catch (AccumuloException ouch1) {
          result.ouch1 = ouch1;
        } catch (AccumuloSecurityException ouch2) {
          result.ouch2 = ouch2;
        } catch (TableNotFoundException ouch3) {
          result.ouch3 = ouch3;
        }
        return result;
      }
    }

    public static class splitRangeByTablets<I extends Iface> extends org.apache.thrift.ProcessFunction<I, splitRangeByTablets_args> {
      public splitRangeByTablets() {
        super("splitRangeByTablets");
      }

      public splitRangeByTablets_args getEmptyArgsInstance() {
        return new splitRangeByTablets_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public splitRangeByTablets_result getResult(I iface, splitRangeByTablets_args args) throws org.apache.thrift.TException {
        splitRangeByTablets_result result = new splitRangeByTablets_result();
        try {
          result.success = iface.splitRangeByTablets(args.login, args.tableName, args.range, args.maxSplits);
        } catch (AccumuloException ouch1) {
          result.ouch1 = ouch1;
        } catch (AccumuloSecurityException ouch2) {
          result.ouch2 = ouch2;
        } catch (TableNotFoundException ouch3) {
          result.ouch3 = ouch3;
        }
        return result;
      }
    }

    public static class tableExists<I extends Iface> extends org.apache.thrift.ProcessFunction<I, tableExists_args> {
      public tableExists() {
        super("tableExists");
      }

      public tableExists_args getEmptyArgsInstance() {
        return new tableExists_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public tableExists_result getResult(I iface, tableExists_args args) throws org.apache.thrift.TException {
        tableExists_result result = new tableExists_result();
        result.success = iface.tableExists(args.login, args.tableName);
        result.setSuccessIsSet(true);
        return result;
      }
    }

    public static class tableIdMap<I extends Iface> extends org.apache.thrift.ProcessFunction<I, tableIdMap_args> {
      public tableIdMap() {
        super("tableIdMap");
      }

      public tableIdMap_args getEmptyArgsInstance() {
        return new tableIdMap_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public tableIdMap_result getResult(I iface, tableIdMap_args args) throws org.apache.thrift.TException {
        tableIdMap_result result = new tableIdMap_result();
        result.success = iface.tableIdMap(args.login);
        return result;
      }
    }

    public static class testTableClassLoad<I extends Iface> extends org.apache.thrift.ProcessFunction<I, testTableClassLoad_args> {
      public testTableClassLoad() {
        super("testTableClassLoad");
      }

      public testTableClassLoad_args getEmptyArgsInstance() {
        return new testTableClassLoad_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public testTableClassLoad_result getResult(I iface, testTableClassLoad_args args) throws org.apache.thrift.TException {
        testTableClassLoad_result result = new testTableClassLoad_result();
        try {
          result.success = iface.testTableClassLoad(args.login, args.tableName, args.className, args.asTypeName);
          result.setSuccessIsSet(true);
        } catch (AccumuloException ouch1) {
          result.ouch1 = ouch1;
        } catch (AccumuloSecurityException ouch2) {
          result.ouch2 = ouch2;
        } catch (TableNotFoundException ouch3) {
          result.ouch3 = ouch3;
        }
        return result;
      }
    }

    public static class pingTabletServer<I extends Iface> extends org.apache.thrift.ProcessFunction<I, pingTabletServer_args> {
      public pingTabletServer() {
        super("pingTabletServer");
      }

      public pingTabletServer_args getEmptyArgsInstance() {
        return new pingTabletServer_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public pingTabletServer_result getResult(I iface, pingTabletServer_args args) throws org.apache.thrift.TException {
        pingTabletServer_result result = new pingTabletServer_result();
        try {
          iface.pingTabletServer(args.login, args.tserver);
        } catch (AccumuloException ouch1) {
          result.ouch1 = ouch1;
        } catch (AccumuloSecurityException ouch2) {
          result.ouch2 = ouch2;
        }
        return result;
      }
    }

    public static class getActiveScans<I extends Iface> extends org.apache.thrift.ProcessFunction<I, getActiveScans_args> {
      public getActiveScans() {
        super("getActiveScans");
      }

      public getActiveScans_args getEmptyArgsInstance() {
        return new getActiveScans_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public getActiveScans_result getResult(I iface, getActiveScans_args args) throws org.apache.thrift.TException {
        getActiveScans_result result = new getActiveScans_result();
        try {
          result.success = iface.getActiveScans(args.login, args.tserver);
        } catch (AccumuloException ouch1) {
          result.ouch1 = ouch1;
        } catch (AccumuloSecurityException ouch2) {
          result.ouch2 = ouch2;
        }
        return result;
      }
    }

    public static class getActiveCompactions<I extends Iface> extends org.apache.thrift.ProcessFunction<I, getActiveCompactions_args> {
      public getActiveCompactions() {
        super("getActiveCompactions");
      }

      public getActiveCompactions_args getEmptyArgsInstance() {
        return new getActiveCompactions_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public getActiveCompactions_result getResult(I iface, getActiveCompactions_args args) throws org.apache.thrift.TException {
        getActiveCompactions_result result = new getActiveCompactions_result();
        try {
          result.success = iface.getActiveCompactions(args.login, args.tserver);
        } catch (AccumuloException ouch1) {
          result.ouch1 = ouch1;
        } catch (AccumuloSecurityException ouch2) {
          result.ouch2 = ouch2;
        }
        return result;
      }
    }

    public static class getSiteConfiguration<I extends Iface> extends org.apache.thrift.ProcessFunction<I, getSiteConfiguration_args> {
      public getSiteConfiguration() {
        super("getSiteConfiguration");
      }

      public getSiteConfiguration_args getEmptyArgsInstance() {
        return new getSiteConfiguration_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public getSiteConfiguration_result getResult(I iface, getSiteConfiguration_args args) throws org.apache.thrift.TException {
        getSiteConfiguration_result result = new getSiteConfiguration_result();
        try {
          result.success = iface.getSiteConfiguration(args.login);
        } catch (AccumuloException ouch1) {
          result.ouch1 = ouch1;
        } catch (AccumuloSecurityException ouch2) {
          result.ouch2 = ouch2;
        }
        return result;
      }
    }

    public static class getSystemConfiguration<I extends Iface> extends org.apache.thrift.ProcessFunction<I, getSystemConfiguration_args> {
      public getSystemConfiguration() {
        super("getSystemConfiguration");
      }

      public getSystemConfiguration_args getEmptyArgsInstance() {
        return new getSystemConfiguration_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public getSystemConfiguration_result getResult(I iface, getSystemConfiguration_args args) throws org.apache.thrift.TException {
        getSystemConfiguration_result result = new getSystemConfiguration_result();
        try {
          result.success = iface.getSystemConfiguration(args.login);
        } catch (AccumuloException ouch1) {
          result.ouch1 = ouch1;
        } catch (AccumuloSecurityException ouch2) {
          result.ouch2 = ouch2;
        }
        return result;
      }
    }

    public static class getTabletServers<I extends Iface> extends org.apache.thrift.ProcessFunction<I, getTabletServers_args> {
      public getTabletServers() {
        super("getTabletServers");
      }

      public getTabletServers_args getEmptyArgsInstance() {
        return new getTabletServers_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public getTabletServers_result getResult(I iface, getTabletServers_args args) throws org.apache.thrift.TException {
        getTabletServers_result result = new getTabletServers_result();
        result.success = iface.getTabletServers(args.login);
        return result;
      }
    }

    public static class removeProperty<I extends Iface> extends org.apache.thrift.ProcessFunction<I, removeProperty_args> {
      public removeProperty() {
        super("removeProperty");
      }

      public removeProperty_args getEmptyArgsInstance() {
        return new removeProperty_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public removeProperty_result getResult(I iface, removeProperty_args args) throws org.apache.thrift.TException {
        removeProperty_result result = new removeProperty_result();
        try {
          iface.removeProperty(args.login, args.property);
        } catch (AccumuloException ouch1) {
          result.ouch1 = ouch1;
        } catch (AccumuloSecurityException ouch2) {
          result.ouch2 = ouch2;
        }
        return result;
      }
    }

    public static class setProperty<I extends Iface> extends org.apache.thrift.ProcessFunction<I, setProperty_args> {
      public setProperty() {
        super("setProperty");
      }

      public setProperty_args getEmptyArgsInstance() {
        return new setProperty_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public setProperty_result getResult(I iface, setProperty_args args) throws org.apache.thrift.TException {
        setProperty_result result = new setProperty_result();
        try {
          iface.setProperty(args.login, args.property, args.value);
        } catch (AccumuloException ouch1) {
          result.ouch1 = ouch1;
        } catch (AccumuloSecurityException ouch2) {
          result.ouch2 = ouch2;
        }
        return result;
      }
    }

    public static class testClassLoad<I extends Iface> extends org.apache.thrift.ProcessFunction<I, testClassLoad_args> {
      public testClassLoad() {
        super("testClassLoad");
      }

      public testClassLoad_args getEmptyArgsInstance() {
        return new testClassLoad_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public testClassLoad_result getResult(I iface, testClassLoad_args args) throws org.apache.thrift.TException {
        testClassLoad_result result = new testClassLoad_result();
        try {
          result.success = iface.testClassLoad(args.login, args.className, args.asTypeName);
          result.setSuccessIsSet(true);
        } catch (AccumuloException ouch1) {
          result.ouch1 = ouch1;
        } catch (AccumuloSecurityException ouch2) {
          result.ouch2 = ouch2;
        }
        return result;
      }
    }

    public static class authenticateUser<I extends Iface> extends org.apache.thrift.ProcessFunction<I, authenticateUser_args> {
      public authenticateUser() {
        super("authenticateUser");
      }

      public authenticateUser_args getEmptyArgsInstance() {
        return new authenticateUser_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public authenticateUser_result getResult(I iface, authenticateUser_args args) throws org.apache.thrift.TException {
        authenticateUser_result result = new authenticateUser_result();
        try {
          result.success = iface.authenticateUser(args.login, args.user, args.properties);
          result.setSuccessIsSet(true);
        } catch (AccumuloException ouch1) {
          result.ouch1 = ouch1;
        } catch (AccumuloSecurityException ouch2) {
          result.ouch2 = ouch2;
        }
        return result;
      }
    }

    public static class changeUserAuthorizations<I extends Iface> extends org.apache.thrift.ProcessFunction<I, changeUserAuthorizations_args> {
      public changeUserAuthorizations() {
        super("changeUserAuthorizations");
      }

      public changeUserAuthorizations_args getEmptyArgsInstance() {
        return new changeUserAuthorizations_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public changeUserAuthorizations_result getResult(I iface, changeUserAuthorizations_args args) throws org.apache.thrift.TException {
        changeUserAuthorizations_result result = new changeUserAuthorizations_result();
        try {
          iface.changeUserAuthorizations(args.login, args.user, args.authorizations);
        } catch (AccumuloException ouch1) {
          result.ouch1 = ouch1;
        } catch (AccumuloSecurityException ouch2) {
          result.ouch2 = ouch2;
        }
        return result;
      }
    }

    public static class changeLocalUserPassword<I extends Iface> extends org.apache.thrift.ProcessFunction<I, changeLocalUserPassword_args> {
      public changeLocalUserPassword() {
        super("changeLocalUserPassword");
      }

      public changeLocalUserPassword_args getEmptyArgsInstance() {
        return new changeLocalUserPassword_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public changeLocalUserPassword_result getResult(I iface, changeLocalUserPassword_args args) throws org.apache.thrift.TException {
        changeLocalUserPassword_result result = new changeLocalUserPassword_result();
        try {
          iface.changeLocalUserPassword(args.login, args.user, args.password);
        } catch (AccumuloException ouch1) {
          result.ouch1 = ouch1;
        } catch (AccumuloSecurityException ouch2) {
          result.ouch2 = ouch2;
        }
        return result;
      }
    }

    public static class createLocalUser<I extends Iface> extends org.apache.thrift.ProcessFunction<I, createLocalUser_args> {
      public createLocalUser() {
        super("createLocalUser");
      }

      public createLocalUser_args getEmptyArgsInstance() {
        return new createLocalUser_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public createLocalUser_result getResult(I iface, createLocalUser_args args) throws org.apache.thrift.TException {
        createLocalUser_result result = new createLocalUser_result();
        try {
          iface.createLocalUser(args.login, args.user, args.password);
        } catch (AccumuloException ouch1) {
          result.ouch1 = ouch1;
        } catch (AccumuloSecurityException ouch2) {
          result.ouch2 = ouch2;
        }
        return result;
      }
    }

    public static class dropLocalUser<I extends Iface> extends org.apache.thrift.ProcessFunction<I, dropLocalUser_args> {
      public dropLocalUser() {
        super("dropLocalUser");
      }

      public dropLocalUser_args getEmptyArgsInstance() {
        return new dropLocalUser_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public dropLocalUser_result getResult(I iface, dropLocalUser_args args) throws org.apache.thrift.TException {
        dropLocalUser_result result = new dropLocalUser_result();
        try {
          iface.dropLocalUser(args.login, args.user);
        } catch (AccumuloException ouch1) {
          result.ouch1 = ouch1;
        } catch (AccumuloSecurityException ouch2) {
          result.ouch2 = ouch2;
        }
        return result;
      }
    }

    public static class getUserAuthorizations<I extends Iface> extends org.apache.thrift.ProcessFunction<I, getUserAuthorizations_args> {
      public getUserAuthorizations() {
        super("getUserAuthorizations");
      }

      public getUserAuthorizations_args getEmptyArgsInstance() {
        return new getUserAuthorizations_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public getUserAuthorizations_result getResult(I iface, getUserAuthorizations_args args) throws org.apache.thrift.TException {
        getUserAuthorizations_result result = new getUserAuthorizations_result();
        try {
          result.success = iface.getUserAuthorizations(args.login, args.user);
        } catch (AccumuloException ouch1) {
          result.ouch1 = ouch1;
        } catch (AccumuloSecurityException ouch2) {
          result.ouch2 = ouch2;
        }
        return result;
      }
    }

    public static class grantSystemPermission<I extends Iface> extends org.apache.thrift.ProcessFunction<I, grantSystemPermission_args> {
      public grantSystemPermission() {
        super("grantSystemPermission");
      }

      public grantSystemPermission_args getEmptyArgsInstance() {
        return new grantSystemPermission_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public grantSystemPermission_result getResult(I iface, grantSystemPermission_args args) throws org.apache.thrift.TException {
        grantSystemPermission_result result = new grantSystemPermission_result();
        try {
          iface.grantSystemPermission(args.login, args.user, args.perm);
        } catch (AccumuloException ouch1) {
          result.ouch1 = ouch1;
        } catch (AccumuloSecurityException ouch2) {
          result.ouch2 = ouch2;
        }
        return result;
      }
    }

    public static class grantTablePermission<I extends Iface> extends org.apache.thrift.ProcessFunction<I, grantTablePermission_args> {
      public grantTablePermission() {
        super("grantTablePermission");
      }

      public grantTablePermission_args getEmptyArgsInstance() {
        return new grantTablePermission_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public grantTablePermission_result getResult(I iface, grantTablePermission_args args) throws org.apache.thrift.TException {
        grantTablePermission_result result = new grantTablePermission_result();
        try {
          iface.grantTablePermission(args.login, args.user, args.table, args.perm);
        } catch (AccumuloException ouch1) {
          result.ouch1 = ouch1;
        } catch (AccumuloSecurityException ouch2) {
          result.ouch2 = ouch2;
        } catch (TableNotFoundException ouch3) {
          result.ouch3 = ouch3;
        }
        return result;
      }
    }

    public static class hasSystemPermission<I extends Iface> extends org.apache.thrift.ProcessFunction<I, hasSystemPermission_args> {
      public hasSystemPermission() {
        super("hasSystemPermission");
      }

      public hasSystemPermission_args getEmptyArgsInstance() {
        return new hasSystemPermission_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public hasSystemPermission_result getResult(I iface, hasSystemPermission_args args) throws org.apache.thrift.TException {
        hasSystemPermission_result result = new hasSystemPermission_result();
        try {
          result.success = iface.hasSystemPermission(args.login, args.user, args.perm);
          result.setSuccessIsSet(true);
        } catch (AccumuloException ouch1) {
          result.ouch1 = ouch1;
        } catch (AccumuloSecurityException ouch2) {
          result.ouch2 = ouch2;
        }
        return result;
      }
    }

    public static class hasTablePermission<I extends Iface> extends org.apache.thrift.ProcessFunction<I, hasTablePermission_args> {
      public hasTablePermission() {
        super("hasTablePermission");
      }

      public hasTablePermission_args getEmptyArgsInstance() {
        return new hasTablePermission_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public hasTablePermission_result getResult(I iface, hasTablePermission_args args) throws org.apache.thrift.TException {
        hasTablePermission_result result = new hasTablePermission_result();
        try {
          result.success = iface.hasTablePermission(args.login, args.user, args.table, args.perm);
          result.setSuccessIsSet(true);
        } catch (AccumuloException ouch1) {
          result.ouch1 = ouch1;
        } catch (AccumuloSecurityException ouch2) {
          result.ouch2 = ouch2;
        } catch (TableNotFoundException ouch3) {
          result.ouch3 = ouch3;
        }
        return result;
      }
    }

    public static class listLocalUsers<I extends Iface> extends org.apache.thrift.ProcessFunction<I, listLocalUsers_args> {
      public listLocalUsers() {
        super("listLocalUsers");
      }

      public listLocalUsers_args getEmptyArgsInstance() {
        return new listLocalUsers_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public listLocalUsers_result getResult(I iface, listLocalUsers_args args) throws org.apache.thrift.TException {
        listLocalUsers_result result = new listLocalUsers_result();
        try {
          result.success = iface.listLocalUsers(args.login);
        } catch (AccumuloException ouch1) {
          result.ouch1 = ouch1;
        } catch (AccumuloSecurityException ouch2) {
          result.ouch2 = ouch2;
        } catch (TableNotFoundException ouch3) {
          result.ouch3 = ouch3;
        }
        return result;
      }
    }

    public static class revokeSystemPermission<I extends Iface> extends org.apache.thrift.ProcessFunction<I, revokeSystemPermission_args> {
      public revokeSystemPermission() {
        super("revokeSystemPermission");
      }

      public revokeSystemPermission_args getEmptyArgsInstance() {
        return new revokeSystemPermission_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public revokeSystemPermission_result getResult(I iface, revokeSystemPermission_args args) throws org.apache.thrift.TException {
        revokeSystemPermission_result result = new revokeSystemPermission_result();
        try {
          iface.revokeSystemPermission(args.login, args.user, args.perm);
        } catch (AccumuloException ouch1) {
          result.ouch1 = ouch1;
        } catch (AccumuloSecurityException ouch2) {
          result.ouch2 = ouch2;
        }
        return result;
      }
    }

    public static class revokeTablePermission<I extends Iface> extends org.apache.thrift.ProcessFunction<I, revokeTablePermission_args> {
      public revokeTablePermission() {
        super("revokeTablePermission");
      }

      public revokeTablePermission_args getEmptyArgsInstance() {
        return new revokeTablePermission_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public revokeTablePermission_result getResult(I iface, revokeTablePermission_args args) throws org.apache.thrift.TException {
        revokeTablePermission_result result = new revokeTablePermission_result();
        try {
          iface.revokeTablePermission(args.login, args.user, args.table, args.perm);
        } catch (AccumuloException ouch1) {
          result.ouch1 = ouch1;
        } catch (AccumuloSecurityException ouch2) {
          result.ouch2 = ouch2;
        } catch (TableNotFoundException ouch3) {
          result.ouch3 = ouch3;
        }
        return result;
      }
    }

    public static class grantNamespacePermission<I extends Iface> extends org.apache.thrift.ProcessFunction<I, grantNamespacePermission_args> {
      public grantNamespacePermission() {
        super("grantNamespacePermission");
      }

      public grantNamespacePermission_args getEmptyArgsInstance() {
        return new grantNamespacePermission_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public grantNamespacePermission_result getResult(I iface, grantNamespacePermission_args args) throws org.apache.thrift.TException {
        grantNamespacePermission_result result = new grantNamespacePermission_result();
        try {
          iface.grantNamespacePermission(args.login, args.user, args.namespaceName, args.perm);
        } catch (AccumuloException ouch1) {
          result.ouch1 = ouch1;
        } catch (AccumuloSecurityException ouch2) {
          result.ouch2 = ouch2;
        }
        return result;
      }
    }

    public static class hasNamespacePermission<I extends Iface> extends org.apache.thrift.ProcessFunction<I, hasNamespacePermission_args> {
      public hasNamespacePermission() {
        super("hasNamespacePermission");
      }

      public hasNamespacePermission_args getEmptyArgsInstance() {
        return new hasNamespacePermission_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public hasNamespacePermission_result getResult(I iface, hasNamespacePermission_args args) throws org.apache.thrift.TException {
        hasNamespacePermission_result result = new hasNamespacePermission_result();
        try {
          result.success = iface.hasNamespacePermission(args.login, args.user, args.namespaceName, args.perm);
          result.setSuccessIsSet(true);
        } catch (AccumuloException ouch1) {
          result.ouch1 = ouch1;
        } catch (AccumuloSecurityException ouch2) {
          result.ouch2 = ouch2;
        }
        return result;
      }
    }

    public static class revokeNamespacePermission<I extends Iface> extends org.apache.thrift.ProcessFunction<I, revokeNamespacePermission_args> {
      public revokeNamespacePermission() {
        super("revokeNamespacePermission");
      }

      public revokeNamespacePermission_args getEmptyArgsInstance() {
        return new revokeNamespacePermission_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public revokeNamespacePermission_result getResult(I iface, revokeNamespacePermission_args args) throws org.apache.thrift.TException {
        revokeNamespacePermission_result result = new revokeNamespacePermission_result();
        try {
          iface.revokeNamespacePermission(args.login, args.user, args.namespaceName, args.perm);
        } catch (AccumuloException ouch1) {
          result.ouch1 = ouch1;
        } catch (AccumuloSecurityException ouch2) {
          result.ouch2 = ouch2;
        }
        return result;
      }
    }

    public static class createBatchScanner<I extends Iface> extends org.apache.thrift.ProcessFunction<I, createBatchScanner_args> {
      public createBatchScanner() {
        super("createBatchScanner");
      }

      public createBatchScanner_args getEmptyArgsInstance() {
        return new createBatchScanner_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public createBatchScanner_result getResult(I iface, createBatchScanner_args args) throws org.apache.thrift.TException {
        createBatchScanner_result result = new createBatchScanner_result();
        try {
          result.success = iface.createBatchScanner(args.login, args.tableName, args.options);
        } catch (AccumuloException ouch1) {
          result.ouch1 = ouch1;
        } catch (AccumuloSecurityException ouch2) {
          result.ouch2 = ouch2;
        } catch (TableNotFoundException ouch3) {
          result.ouch3 = ouch3;
        }
        return result;
      }
    }

    public static class createScanner<I extends Iface> extends org.apache.thrift.ProcessFunction<I, createScanner_args> {
      public createScanner() {
        super("createScanner");
      }

      public createScanner_args getEmptyArgsInstance() {
        return new createScanner_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public createScanner_result getResult(I iface, createScanner_args args) throws org.apache.thrift.TException {
        createScanner_result result = new createScanner_result();
        try {
          result.success = iface.createScanner(args.login, args.tableName, args.options);
        } catch (AccumuloException ouch1) {
          result.ouch1 = ouch1;
        } catch (AccumuloSecurityException ouch2) {
          result.ouch2 = ouch2;
        } catch (TableNotFoundException ouch3) {
          result.ouch3 = ouch3;
        }
        return result;
      }
    }

    public static class hasNext<I extends Iface> extends org.apache.thrift.ProcessFunction<I, hasNext_args> {
      public hasNext() {
        super("hasNext");
      }

      public hasNext_args getEmptyArgsInstance() {
        return new hasNext_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public hasNext_result getResult(I iface, hasNext_args args) throws org.apache.thrift.TException {
        hasNext_result result = new hasNext_result();
        try {
          result.success = iface.hasNext(args.scanner);
          result.setSuccessIsSet(true);
        } catch (UnknownScanner ouch1) {
          result.ouch1 = ouch1;
        }
        return result;
      }
    }

    public static class nextEntry<I extends Iface> extends org.apache.thrift.ProcessFunction<I, nextEntry_args> {
      public nextEntry() {
        super("nextEntry");
      }

      public nextEntry_args getEmptyArgsInstance() {
        return new nextEntry_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public nextEntry_result getResult(I iface, nextEntry_args args) throws org.apache.thrift.TException {
        nextEntry_result result = new nextEntry_result();
        try {
          result.success = iface.nextEntry(args.scanner);
        } catch (NoMoreEntriesException ouch1) {
          result.ouch1 = ouch1;
        } catch (UnknownScanner ouch2) {
          result.ouch2 = ouch2;
        } catch (AccumuloSecurityException ouch3) {
          result.ouch3 = ouch3;
        }
        return result;
      }
    }

    public static class nextK<I extends Iface> extends org.apache.thrift.ProcessFunction<I, nextK_args> {
      public nextK() {
        super("nextK");
      }

      public nextK_args getEmptyArgsInstance() {
        return new nextK_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public nextK_result getResult(I iface, nextK_args args) throws org.apache.thrift.TException {
        nextK_result result = new nextK_result();
        try {
          result.success = iface.nextK(args.scanner, args.k);
        } catch (NoMoreEntriesException ouch1) {
          result.ouch1 = ouch1;
        } catch (UnknownScanner ouch2) {
          result.ouch2 = ouch2;
        } catch (AccumuloSecurityException ouch3) {
          result.ouch3 = ouch3;
        }
        return result;
      }
    }

    public static class closeScanner<I extends Iface> extends org.apache.thrift.ProcessFunction<I, closeScanner_args> {
      public closeScanner() {
        super("closeScanner");
      }

      public closeScanner_args getEmptyArgsInstance() {
        return new closeScanner_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public closeScanner_result getResult(I iface, closeScanner_args args) throws org.apache.thrift.TException {
        closeScanner_result result = new closeScanner_result();
        try {
          iface.closeScanner(args.scanner);
        } catch (UnknownScanner ouch1) {
          result.ouch1 = ouch1;
        }
        return result;
      }
    }

    public static class updateAndFlush<I extends Iface> extends org.apache.thrift.ProcessFunction<I, updateAndFlush_args> {
      public updateAndFlush() {
        super("updateAndFlush");
      }

      public updateAndFlush_args getEmptyArgsInstance() {
        return new updateAndFlush_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public updateAndFlush_result getResult(I iface, updateAndFlush_args args) throws org.apache.thrift.TException {
        updateAndFlush_result result = new updateAndFlush_result();
        try {
          iface.updateAndFlush(args.login, args.tableName, args.cells);
        } catch (AccumuloException outch1) {
          result.outch1 = outch1;
        } catch (AccumuloSecurityException ouch2) {
          result.ouch2 = ouch2;
        } catch (TableNotFoundException ouch3) {
          result.ouch3 = ouch3;
        } catch (MutationsRejectedException ouch4) {
          result.ouch4 = ouch4;
        }
        return result;
      }
    }

    public static class createWriter<I extends Iface> extends org.apache.thrift.ProcessFunction<I, createWriter_args> {
      public createWriter() {
        super("createWriter");
      }

      public createWriter_args getEmptyArgsInstance() {
        return new createWriter_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public createWriter_result getResult(I iface, createWriter_args args) throws org.apache.thrift.TException {
        createWriter_result result = new createWriter_result();
        try {
          result.success = iface.createWriter(args.login, args.tableName, args.opts);
        } catch (AccumuloException outch1) {
          result.outch1 = outch1;
        } catch (AccumuloSecurityException ouch2) {
          result.ouch2 = ouch2;
        } catch (TableNotFoundException ouch3) {
          result.ouch3 = ouch3;
        }
        return result;
      }
    }

    public static class update<I extends Iface> extends org.apache.thrift.ProcessFunction<I, update_args> {
      public update() {
        super("update");
      }

      public update_args getEmptyArgsInstance() {
        return new update_args();
      }

      protected boolean isOneway() {
        return true;
      }

      public org.apache.thrift.TBase getResult(I iface, update_args args) throws org.apache.thrift.TException {
        iface.update(args.writer, args.cells);
        return null;
      }
    }

    public static class flush<I extends Iface> extends org.apache.thrift.ProcessFunction<I, flush_args> {
      public flush() {
        super("flush");
      }

      public flush_args getEmptyArgsInstance() {
        return new flush_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public flush_result getResult(I iface, flush_args args) throws org.apache.thrift.TException {
        flush_result result = new flush_result();
        try {
          iface.flush(args.writer);
        } catch (UnknownWriter ouch1) {
          result.ouch1 = ouch1;
        } catch (MutationsRejectedException ouch2) {
          result.ouch2 = ouch2;
        }
        return result;
      }
    }

    public static class closeWriter<I extends Iface> extends org.apache.thrift.ProcessFunction<I, closeWriter_args> {
      public closeWriter() {
        super("closeWriter");
      }

      public closeWriter_args getEmptyArgsInstance() {
        return new closeWriter_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public closeWriter_result getResult(I iface, closeWriter_args args) throws org.apache.thrift.TException {
        closeWriter_result result = new closeWriter_result();
        try {
          iface.closeWriter(args.writer);
        } catch (UnknownWriter ouch1) {
          result.ouch1 = ouch1;
        } catch (MutationsRejectedException ouch2) {
          result.ouch2 = ouch2;
        }
        return result;
      }
    }

    public static class updateRowConditionally<I extends Iface> extends org.apache.thrift.ProcessFunction<I, updateRowConditionally_args> {
      public updateRowConditionally() {
        super("updateRowConditionally");
      }

      public updateRowConditionally_args getEmptyArgsInstance() {
        return new updateRowConditionally_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public updateRowConditionally_result getResult(I iface, updateRowConditionally_args args) throws org.apache.thrift.TException {
        updateRowConditionally_result result = new updateRowConditionally_result();
        try {
          result.success = iface.updateRowConditionally(args.login, args.tableName, args.row, args.updates);
        } catch (AccumuloException ouch1) {
          result.ouch1 = ouch1;
        } catch (AccumuloSecurityException ouch2) {
          result.ouch2 = ouch2;
        } catch (TableNotFoundException ouch3) {
          result.ouch3 = ouch3;
        }
        return result;
      }
    }

    public static class createConditionalWriter<I extends Iface> extends org.apache.thrift.ProcessFunction<I, createConditionalWriter_args> {
      public createConditionalWriter() {
        super("createConditionalWriter");
      }

      public createConditionalWriter_args getEmptyArgsInstance() {
        return new createConditionalWriter_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public createConditionalWriter_result getResult(I iface, createConditionalWriter_args args) throws org.apache.thrift.TException {
        createConditionalWriter_result result = new createConditionalWriter_result();
        try {
          result.success = iface.createConditionalWriter(args.login, args.tableName, args.options);
        } catch (AccumuloException ouch1) {
          result.ouch1 = ouch1;
        } catch (AccumuloSecurityException ouch2) {
          result.ouch2 = ouch2;
        } catch (TableNotFoundException ouch3) {
          result.ouch3 = ouch3;
        }
        return result;
      }
    }

    public static class updateRowsConditionally<I extends Iface> extends org.apache.thrift.ProcessFunction<I, updateRowsConditionally_args> {
      public updateRowsConditionally() {
        super("updateRowsConditionally");
      }

      public updateRowsConditionally_args getEmptyArgsInstance() {
        return new updateRowsConditionally_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public updateRowsConditionally_result getResult(I iface, updateRowsConditionally_args args) throws org.apache.thrift.TException {
        updateRowsConditionally_result result = new updateRowsConditionally_result();
        try {
          result.success = iface.updateRowsConditionally(args.conditionalWriter, args.updates);
        } catch (UnknownWriter ouch1) {
          result.ouch1 = ouch1;
        } catch (AccumuloException ouch2) {
          result.ouch2 = ouch2;
        } catch (AccumuloSecurityException ouch3) {
          result.ouch3 = ouch3;
        }
        return result;
      }
    }

    public static class closeConditionalWriter<I extends Iface> extends org.apache.thrift.ProcessFunction<I, closeConditionalWriter_args> {
      public closeConditionalWriter() {
        super("closeConditionalWriter");
      }

      public closeConditionalWriter_args getEmptyArgsInstance() {
        return new closeConditionalWriter_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public closeConditionalWriter_result getResult(I iface, closeConditionalWriter_args args) throws org.apache.thrift.TException {
        closeConditionalWriter_result result = new closeConditionalWriter_result();
        iface.closeConditionalWriter(args.conditionalWriter);
        return result;
      }
    }

    public static class getRowRange<I extends Iface> extends org.apache.thrift.ProcessFunction<I, getRowRange_args> {
      public getRowRange() {
        super("getRowRange");
      }

      public getRowRange_args getEmptyArgsInstance() {
        return new getRowRange_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public getRowRange_result getResult(I iface, getRowRange_args args) throws org.apache.thrift.TException {
        getRowRange_result result = new getRowRange_result();
        result.success = iface.getRowRange(args.row);
        return result;
      }
    }

    public static class getFollowing<I extends Iface> extends org.apache.thrift.ProcessFunction<I, getFollowing_args> {
      public getFollowing() {
        super("getFollowing");
      }

      public getFollowing_args getEmptyArgsInstance() {
        return new getFollowing_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public getFollowing_result getResult(I iface, getFollowing_args args) throws org.apache.thrift.TException {
        getFollowing_result result = new getFollowing_result();
        result.success = iface.getFollowing(args.key, args.part);
        return result;
      }
    }

    public static class systemNamespace<I extends Iface> extends org.apache.thrift.ProcessFunction<I, systemNamespace_args> {
      public systemNamespace() {
        super("systemNamespace");
      }

      public systemNamespace_args getEmptyArgsInstance() {
        return new systemNamespace_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public systemNamespace_result getResult(I iface, systemNamespace_args args) throws org.apache.thrift.TException {
        systemNamespace_result result = new systemNamespace_result();
        result.success = iface.systemNamespace();
        return result;
      }
    }

    public static class defaultNamespace<I extends Iface> extends org.apache.thrift.ProcessFunction<I, defaultNamespace_args> {
      public defaultNamespace() {
        super("defaultNamespace");
      }

      public defaultNamespace_args getEmptyArgsInstance() {
        return new defaultNamespace_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public defaultNamespace_result getResult(I iface, defaultNamespace_args args) throws org.apache.thrift.TException {
        defaultNamespace_result result = new defaultNamespace_result();
        result.success = iface.defaultNamespace();
        return result;
      }
    }

    public static class listNamespaces<I extends Iface> extends org.apache.thrift.ProcessFunction<I, listNamespaces_args> {
      public listNamespaces() {
        super("listNamespaces");
      }

      public listNamespaces_args getEmptyArgsInstance() {
        return new listNamespaces_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public listNamespaces_result getResult(I iface, listNamespaces_args args) throws org.apache.thrift.TException {
        listNamespaces_result result = new listNamespaces_result();
        try {
          result.success = iface.listNamespaces(args.login);
        } catch (AccumuloException ouch1) {
          result.ouch1 = ouch1;
        } catch (AccumuloSecurityException ouch2) {
          result.ouch2 = ouch2;
        }
        return result;
      }
    }

    public static class namespaceExists<I extends Iface> extends org.apache.thrift.ProcessFunction<I, namespaceExists_args> {
      public namespaceExists() {
        super("namespaceExists");
      }

      public namespaceExists_args getEmptyArgsInstance() {
        return new namespaceExists_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public namespaceExists_result getResult(I iface, namespaceExists_args args) throws org.apache.thrift.TException {
        namespaceExists_result result = new namespaceExists_result();
        try {
          result.success = iface.namespaceExists(args.login, args.namespaceName);
          result.setSuccessIsSet(true);
        } catch (AccumuloException ouch1) {
          result.ouch1 = ouch1;
        } catch (AccumuloSecurityException ouch2) {
          result.ouch2 = ouch2;
        }
        return result;
      }
    }

    public static class createNamespace<I extends Iface> extends org.apache.thrift.ProcessFunction<I, createNamespace_args> {
      public createNamespace() {
        super("createNamespace");
      }

      public createNamespace_args getEmptyArgsInstance() {
        return new createNamespace_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public createNamespace_result getResult(I iface, createNamespace_args args) throws org.apache.thrift.TException {
        createNamespace_result result = new createNamespace_result();
        try {
          iface.createNamespace(args.login, args.namespaceName);
        } catch (AccumuloException ouch1) {
          result.ouch1 = ouch1;
        } catch (AccumuloSecurityException ouch2) {
          result.ouch2 = ouch2;
        } catch (NamespaceExistsException ouch3) {
          result.ouch3 = ouch3;
        }
        return result;
      }
    }

    public static class deleteNamespace<I extends Iface> extends org.apache.thrift.ProcessFunction<I, deleteNamespace_args> {
      public deleteNamespace() {
        super("deleteNamespace");
      }

      public deleteNamespace_args getEmptyArgsInstance() {
        return new deleteNamespace_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public deleteNamespace_result getResult(I iface, deleteNamespace_args args) throws org.apache.thrift.TException {
        deleteNamespace_result result = new deleteNamespace_result();
        try {
          iface.deleteNamespace(args.login, args.namespaceName);
        } catch (AccumuloException ouch1) {
          result.ouch1 = ouch1;
        } catch (AccumuloSecurityException ouch2) {
          result.ouch2 = ouch2;
        } catch (NamespaceNotFoundException ouch3) {
          result.ouch3 = ouch3;
        } catch (NamespaceNotEmptyException ouch4) {
          result.ouch4 = ouch4;
        }
        return result;
      }
    }

    public static class renameNamespace<I extends Iface> extends org.apache.thrift.ProcessFunction<I, renameNamespace_args> {
      public renameNamespace() {
        super("renameNamespace");
      }

      public renameNamespace_args getEmptyArgsInstance() {
        return new renameNamespace_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public renameNamespace_result getResult(I iface, renameNamespace_args args) throws org.apache.thrift.TException {
        renameNamespace_result result = new renameNamespace_result();
        try {
          iface.renameNamespace(args.login, args.oldNamespaceName, args.newNamespaceName);
        } catch (AccumuloException ouch1) {
          result.ouch1 = ouch1;
        } catch (AccumuloSecurityException ouch2) {
          result.ouch2 = ouch2;
        } catch (NamespaceNotFoundException ouch3) {
          result.ouch3 = ouch3;
        } catch (NamespaceExistsException ouch4) {
          result.ouch4 = ouch4;
        }
        return result;
      }
    }

    public static class setNamespaceProperty<I extends Iface> extends org.apache.thrift.ProcessFunction<I, setNamespaceProperty_args> {
      public setNamespaceProperty() {
        super("setNamespaceProperty");
      }

      public setNamespaceProperty_args getEmptyArgsInstance() {
        return new setNamespaceProperty_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public setNamespaceProperty_result getResult(I iface, setNamespaceProperty_args args) throws org.apache.thrift.TException {
        setNamespaceProperty_result result = new setNamespaceProperty_result();
        try {
          iface.setNamespaceProperty(args.login, args.namespaceName, args.property, args.value);
        } catch (AccumuloException ouch1) {
          result.ouch1 = ouch1;
        } catch (AccumuloSecurityException ouch2) {
          result.ouch2 = ouch2;
        } catch (NamespaceNotFoundException ouch3) {
          result.ouch3 = ouch3;
        }
        return result;
      }
    }

    public static class removeNamespaceProperty<I extends Iface> extends org.apache.thrift.ProcessFunction<I, removeNamespaceProperty_args> {
      public removeNamespaceProperty() {
        super("removeNamespaceProperty");
      }

      public removeNamespaceProperty_args getEmptyArgsInstance() {
        return new removeNamespaceProperty_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public removeNamespaceProperty_result getResult(I iface, removeNamespaceProperty_args args) throws org.apache.thrift.TException {
        removeNamespaceProperty_result result = new removeNamespaceProperty_result();
        try {
          iface.removeNamespaceProperty(args.login, args.namespaceName, args.property);
        } catch (AccumuloException ouch1) {
          result.ouch1 = ouch1;
        } catch (AccumuloSecurityException ouch2) {
          result.ouch2 = ouch2;
        } catch (NamespaceNotFoundException ouch3) {
          result.ouch3 = ouch3;
        }
        return result;
      }
    }

    public static class getNamespaceProperties<I extends Iface> extends org.apache.thrift.ProcessFunction<I, getNamespaceProperties_args> {
      public getNamespaceProperties() {
        super("getNamespaceProperties");
      }

      public getNamespaceProperties_args getEmptyArgsInstance() {
        return new getNamespaceProperties_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public getNamespaceProperties_result getResult(I iface, getNamespaceProperties_args args) throws org.apache.thrift.TException {
        getNamespaceProperties_result result = new getNamespaceProperties_result();
        try {
          result.success = iface.getNamespaceProperties(args.login, args.namespaceName);
        } catch (AccumuloException ouch1) {
          result.ouch1 = ouch1;
        } catch (AccumuloSecurityException ouch2) {
          result.ouch2 = ouch2;
        } catch (NamespaceNotFoundException ouch3) {
          result.ouch3 = ouch3;
        }
        return result;
      }
    }

    public static class namespaceIdMap<I extends Iface> extends org.apache.thrift.ProcessFunction<I, namespaceIdMap_args> {
      public namespaceIdMap() {
        super("namespaceIdMap");
      }

      public namespaceIdMap_args getEmptyArgsInstance() {
        return new namespaceIdMap_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public namespaceIdMap_result getResult(I iface, namespaceIdMap_args args) throws org.apache.thrift.TException {
        namespaceIdMap_result result = new namespaceIdMap_result();
        try {
          result.success = iface.namespaceIdMap(args.login);
        } catch (AccumuloException ouch1) {
          result.ouch1 = ouch1;
        } catch (AccumuloSecurityException ouch2) {
          result.ouch2 = ouch2;
        }
        return result;
      }
    }

    public static class attachNamespaceIterator<I extends Iface> extends org.apache.thrift.ProcessFunction<I, attachNamespaceIterator_args> {
      public attachNamespaceIterator() {
        super("attachNamespaceIterator");
      }

      public attachNamespaceIterator_args getEmptyArgsInstance() {
        return new attachNamespaceIterator_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public attachNamespaceIterator_result getResult(I iface, attachNamespaceIterator_args args) throws org.apache.thrift.TException {
        attachNamespaceIterator_result result = new attachNamespaceIterator_result();
        try {
          iface.attachNamespaceIterator(args.login, args.namespaceName, args.setting, args.scopes);
        } catch (AccumuloException ouch1) {
          result.ouch1 = ouch1;
        } catch (AccumuloSecurityException ouch2) {
          result.ouch2 = ouch2;
        } catch (NamespaceNotFoundException ouch3) {
          result.ouch3 = ouch3;
        }
        return result;
      }
    }

    public static class removeNamespaceIterator<I extends Iface> extends org.apache.thrift.ProcessFunction<I, removeNamespaceIterator_args> {
      public removeNamespaceIterator() {
        super("removeNamespaceIterator");
      }

      public removeNamespaceIterator_args getEmptyArgsInstance() {
        return new removeNamespaceIterator_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public removeNamespaceIterator_result getResult(I iface, removeNamespaceIterator_args args) throws org.apache.thrift.TException {
        removeNamespaceIterator_result result = new removeNamespaceIterator_result();
        try {
          iface.removeNamespaceIterator(args.login, args.namespaceName, args.name, args.scopes);
        } catch (AccumuloException ouch1) {
          result.ouch1 = ouch1;
        } catch (AccumuloSecurityException ouch2) {
          result.ouch2 = ouch2;
        } catch (NamespaceNotFoundException ouch3) {
          result.ouch3 = ouch3;
        }
        return result;
      }
    }

    public static class getNamespaceIteratorSetting<I extends Iface> extends org.apache.thrift.ProcessFunction<I, getNamespaceIteratorSetting_args> {
      public getNamespaceIteratorSetting() {
        super("getNamespaceIteratorSetting");
      }

      public getNamespaceIteratorSetting_args getEmptyArgsInstance() {
        return new getNamespaceIteratorSetting_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public getNamespaceIteratorSetting_result getResult(I iface, getNamespaceIteratorSetting_args args) throws org.apache.thrift.TException {
        getNamespaceIteratorSetting_result result = new getNamespaceIteratorSetting_result();
        try {
          result.success = iface.getNamespaceIteratorSetting(args.login, args.namespaceName, args.name, args.scope);
        } catch (AccumuloException ouch1) {
          result.ouch1 = ouch1;
        } catch (AccumuloSecurityException ouch2) {
          result.ouch2 = ouch2;
        } catch (NamespaceNotFoundException ouch3) {
          result.ouch3 = ouch3;
        }
        return result;
      }
    }

    public static class listNamespaceIterators<I extends Iface> extends org.apache.thrift.ProcessFunction<I, listNamespaceIterators_args> {
      public listNamespaceIterators() {
        super("listNamespaceIterators");
      }

      public listNamespaceIterators_args getEmptyArgsInstance() {
        return new listNamespaceIterators_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public listNamespaceIterators_result getResult(I iface, listNamespaceIterators_args args) throws org.apache.thrift.TException {
        listNamespaceIterators_result result = new listNamespaceIterators_result();
        try {
          result.success = iface.listNamespaceIterators(args.login, args.namespaceName);
        } catch (AccumuloException ouch1) {
          result.ouch1 = ouch1;
        } catch (AccumuloSecurityException ouch2) {
          result.ouch2 = ouch2;
        } catch (NamespaceNotFoundException ouch3) {
          result.ouch3 = ouch3;
        }
        return result;
      }
    }

    public static class checkNamespaceIteratorConflicts<I extends Iface> extends org.apache.thrift.ProcessFunction<I, checkNamespaceIteratorConflicts_args> {
      public checkNamespaceIteratorConflicts() {
        super("checkNamespaceIteratorConflicts");
      }

      public checkNamespaceIteratorConflicts_args getEmptyArgsInstance() {
        return new checkNamespaceIteratorConflicts_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public checkNamespaceIteratorConflicts_result getResult(I iface, checkNamespaceIteratorConflicts_args args) throws org.apache.thrift.TException {
        checkNamespaceIteratorConflicts_result result = new checkNamespaceIteratorConflicts_result();
        try {
          iface.checkNamespaceIteratorConflicts(args.login, args.namespaceName, args.setting, args.scopes);
        } catch (AccumuloException ouch1) {
          result.ouch1 = ouch1;
        } catch (AccumuloSecurityException ouch2) {
          result.ouch2 = ouch2;
        } catch (NamespaceNotFoundException ouch3) {
          result.ouch3 = ouch3;
        }
        return result;
      }
    }

    public static class addNamespaceConstraint<I extends Iface> extends org.apache.thrift.ProcessFunction<I, addNamespaceConstraint_args> {
      public addNamespaceConstraint() {
        super("addNamespaceConstraint");
      }

      public addNamespaceConstraint_args getEmptyArgsInstance() {
        return new addNamespaceConstraint_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public addNamespaceConstraint_result getResult(I iface, addNamespaceConstraint_args args) throws org.apache.thrift.TException {
        addNamespaceConstraint_result result = new addNamespaceConstraint_result();
        try {
          result.success = iface.addNamespaceConstraint(args.login, args.namespaceName, args.constraintClassName);
          result.setSuccessIsSet(true);
        } catch (AccumuloException ouch1) {
          result.ouch1 = ouch1;
        } catch (AccumuloSecurityException ouch2) {
          result.ouch2 = ouch2;
        } catch (NamespaceNotFoundException ouch3) {
          result.ouch3 = ouch3;
        }
        return result;
      }
    }

    public static class removeNamespaceConstraint<I extends Iface> extends org.apache.thrift.ProcessFunction<I, removeNamespaceConstraint_args> {
      public removeNamespaceConstraint() {
        super("removeNamespaceConstraint");
      }

      public removeNamespaceConstraint_args getEmptyArgsInstance() {
        return new removeNamespaceConstraint_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public removeNamespaceConstraint_result getResult(I iface, removeNamespaceConstraint_args args) throws org.apache.thrift.TException {
        removeNamespaceConstraint_result result = new removeNamespaceConstraint_result();
        try {
          iface.removeNamespaceConstraint(args.login, args.namespaceName, args.id);
        } catch (AccumuloException ouch1) {
          result.ouch1 = ouch1;
        } catch (AccumuloSecurityException ouch2) {
          result.ouch2 = ouch2;
        } catch (NamespaceNotFoundException ouch3) {
          result.ouch3 = ouch3;
        }
        return result;
      }
    }

    public static class listNamespaceConstraints<I extends Iface> extends org.apache.thrift.ProcessFunction<I, listNamespaceConstraints_args> {
      public listNamespaceConstraints() {
        super("listNamespaceConstraints");
      }

      public listNamespaceConstraints_args getEmptyArgsInstance() {
        return new listNamespaceConstraints_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public listNamespaceConstraints_result getResult(I iface, listNamespaceConstraints_args args) throws org.apache.thrift.TException {
        listNamespaceConstraints_result result = new listNamespaceConstraints_result();
        try {
          result.success = iface.listNamespaceConstraints(args.login, args.namespaceName);
        } catch (AccumuloException ouch1) {
          result.ouch1 = ouch1;
        } catch (AccumuloSecurityException ouch2) {
          result.ouch2 = ouch2;
        } catch (NamespaceNotFoundException ouch3) {
          result.ouch3 = ouch3;
        }
        return result;
      }
    }

    public static class testNamespaceClassLoad<I extends Iface> extends org.apache.thrift.ProcessFunction<I, testNamespaceClassLoad_args> {
      public testNamespaceClassLoad() {
        super("testNamespaceClassLoad");
      }

      public testNamespaceClassLoad_args getEmptyArgsInstance() {
        return new testNamespaceClassLoad_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public testNamespaceClassLoad_result getResult(I iface, testNamespaceClassLoad_args args) throws org.apache.thrift.TException {
        testNamespaceClassLoad_result result = new testNamespaceClassLoad_result();
        try {
          result.success = iface.testNamespaceClassLoad(args.login, args.namespaceName, args.className, args.asTypeName);
          result.setSuccessIsSet(true);
        } catch (AccumuloException ouch1) {
          result.ouch1 = ouch1;
        } catch (AccumuloSecurityException ouch2) {
          result.ouch2 = ouch2;
        } catch (NamespaceNotFoundException ouch3) {
          result.ouch3 = ouch3;
        }
        return result;
      }
    }

  }

  public static class AsyncProcessor<I extends AsyncIface> extends org.apache.thrift.TBaseAsyncProcessor<I> {
    private static final org.slf4j.Logger _LOGGER = org.slf4j.LoggerFactory.getLogger(AsyncProcessor.class.getName());
    public AsyncProcessor(I iface) {
      super(iface, getProcessMap(new java.util.HashMap<java.lang.String, org.apache.thrift.AsyncProcessFunction<I, ? extends org.apache.thrift.TBase, ?>>()));
    }

    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> 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());
      processMap.put("attachIterator", new attachIterator());
      processMap.put("checkIteratorConflicts", new checkIteratorConflicts());
      processMap.put("clearLocatorCache", new clearLocatorCache());
      processMap.put("cloneTable", new cloneTable());
      processMap.put("compactTable", new compactTable());
      processMap.put("cancelCompaction", new cancelCompaction());
      processMap.put("createTable", new createTable());
      processMap.put("deleteTable", new deleteTable());
      processMap.put("deleteRows", new deleteRows());
      processMap.put("exportTable", new exportTable());
      processMap.put("flushTable", new flushTable());
      processMap.put("getDiskUsage", new getDiskUsage());
      processMap.put("getLocalityGroups", new getLocalityGroups());
      processMap.put("getIteratorSetting", new getIteratorSetting());
      processMap.put("getMaxRow", new getMaxRow());
      processMap.put("getTableProperties", new getTableProperties());
      processMap.put("importDirectory", new importDirectory());
      processMap.put("importTable", new importTable());
      processMap.put("listSplits", new listSplits());
      processMap.put("listTables", new listTables());
      processMap.put("listIterators", new listIterators());
      processMap.put("listConstraints", new listConstraints());
      processMap.put("mergeTablets", new mergeTablets());
      processMap.put("offlineTable", new offlineTable());
      processMap.put("onlineTable", new onlineTable());
      processMap.put("removeConstraint", new removeConstraint());
      processMap.put("removeIterator", new removeIterator());
      processMap.put("removeTableProperty", new removeTableProperty());
      processMap.put("renameTable", new renameTable());
      processMap.put("setLocalityGroups", new setLocalityGroups());
      processMap.put("setTableProperty", new setTableProperty());
      processMap.put("splitRangeByTablets", new splitRangeByTablets());
      processMap.put("tableExists", new tableExists());
      processMap.put("tableIdMap", new tableIdMap());
      processMap.put("testTableClassLoad", new testTableClassLoad());
      processMap.put("pingTabletServer", new pingTabletServer());
      processMap.put("getActiveScans", new getActiveScans());
      processMap.put("getActiveCompactions", new getActiveCompactions());
      processMap.put("getSiteConfiguration", new getSiteConfiguration());
      processMap.put("getSystemConfiguration", new getSystemConfiguration());
      processMap.put("getTabletServers", new getTabletServers());
      processMap.put("removeProperty", new removeProperty());
      processMap.put("setProperty", new setProperty());
      processMap.put("testClassLoad", new testClassLoad());
      processMap.put("authenticateUser", new authenticateUser());
      processMap.put("changeUserAuthorizations", new changeUserAuthorizations());
      processMap.put("changeLocalUserPassword", new changeLocalUserPassword());
      processMap.put("createLocalUser", new createLocalUser());
      processMap.put("dropLocalUser", new dropLocalUser());
      processMap.put("getUserAuthorizations", new getUserAuthorizations());
      processMap.put("grantSystemPermission", new grantSystemPermission());
      processMap.put("grantTablePermission", new grantTablePermission());
      processMap.put("hasSystemPermission", new hasSystemPermission());
      processMap.put("hasTablePermission", new hasTablePermission());
      processMap.put("listLocalUsers", new listLocalUsers());
      processMap.put("revokeSystemPermission", new revokeSystemPermission());
      processMap.put("revokeTablePermission", new revokeTablePermission());
      processMap.put("grantNamespacePermission", new grantNamespacePermission());
      processMap.put("hasNamespacePermission", new hasNamespacePermission());
      processMap.put("revokeNamespacePermission", new revokeNamespacePermission());
      processMap.put("createBatchScanner", new createBatchScanner());
      processMap.put("createScanner", new createScanner());
      processMap.put("hasNext", new hasNext());
      processMap.put("nextEntry", new nextEntry());
      processMap.put("nextK", new nextK());
      processMap.put("closeScanner", new closeScanner());
      processMap.put("updateAndFlush", new updateAndFlush());
      processMap.put("createWriter", new createWriter());
      processMap.put("update", new update());
      processMap.put("flush", new flush());
      processMap.put("closeWriter", new closeWriter());
      processMap.put("updateRowConditionally", new updateRowConditionally());
      processMap.put("createConditionalWriter", new createConditionalWriter());
      processMap.put("updateRowsConditionally", new updateRowsConditionally());
      processMap.put("closeConditionalWriter", new closeConditionalWriter());
      processMap.put("getRowRange", new getRowRange());
      processMap.put("getFollowing", new getFollowing());
      processMap.put("systemNamespace", new systemNamespace());
      processMap.put("defaultNamespace", new defaultNamespace());
      processMap.put("listNamespaces", new listNamespaces());
      processMap.put("namespaceExists", new namespaceExists());
      processMap.put("createNamespace", new createNamespace());
      processMap.put("deleteNamespace", new deleteNamespace());
      processMap.put("renameNamespace", new renameNamespace());
      processMap.put("setNamespaceProperty", new setNamespaceProperty());
      processMap.put("removeNamespaceProperty", new removeNamespaceProperty());
      processMap.put("getNamespaceProperties", new getNamespaceProperties());
      processMap.put("namespaceIdMap", new namespaceIdMap());
      processMap.put("attachNamespaceIterator", new attachNamespaceIterator());
      processMap.put("removeNamespaceIterator", new removeNamespaceIterator());
      processMap.put("getNamespaceIteratorSetting", new getNamespaceIteratorSetting());
      processMap.put("listNamespaceIterators", new listNamespaceIterators());
      processMap.put("checkNamespaceIteratorConflicts", new checkNamespaceIteratorConflicts());
      processMap.put("addNamespaceConstraint", new addNamespaceConstraint());
      processMap.put("removeNamespaceConstraint", new removeNamespaceConstraint());
      processMap.put("listNamespaceConstraints", new listNamespaceConstraints());
      processMap.put("testNamespaceClassLoad", new testNamespaceClassLoad());
      return processMap;
    }

    public static class login<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, login_args, java.nio.ByteBuffer> {
      public login() {
        super("login");
      }

      public login_args getEmptyArgsInstance() {
        return new login_args();
      }

      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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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 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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      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, java.lang.Integer> {
      public addConstraint() {
        super("addConstraint");
      }

      public addConstraint_args getEmptyArgsInstance() {
        return new addConstraint_args();
      }

      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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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 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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

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

    public static class addSplits<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, addSplits_args, Void> {
      public addSplits() {
        super("addSplits");
      }

      public addSplits_args getEmptyArgsInstance() {
        return new addSplits_args();
      }

      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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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 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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

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

    public static class attachIterator<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, attachIterator_args, Void> {
      public attachIterator() {
        super("attachIterator");
      }

      public attachIterator_args getEmptyArgsInstance() {
        return new attachIterator_args();
      }

      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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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 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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

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

    public static class checkIteratorConflicts<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, checkIteratorConflicts_args, Void> {
      public checkIteratorConflicts() {
        super("checkIteratorConflicts");
      }

      public checkIteratorConflicts_args getEmptyArgsInstance() {
        return new checkIteratorConflicts_args();
      }

      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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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 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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

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

    public static class clearLocatorCache<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, clearLocatorCache_args, Void> {
      public clearLocatorCache() {
        super("clearLocatorCache");
      }

      public clearLocatorCache_args getEmptyArgsInstance() {
        return new clearLocatorCache_args();
      }

      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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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 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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

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

    public static class cloneTable<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, cloneTable_args, Void> {
      public cloneTable() {
        super("cloneTable");
      }

      public cloneTable_args getEmptyArgsInstance() {
        return new cloneTable_args();
      }

      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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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 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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

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

    public static class compactTable<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, compactTable_args, Void> {
      public compactTable() {
        super("compactTable");
      }

      public compactTable_args getEmptyArgsInstance() {
        return new compactTable_args();
      }

      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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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 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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

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

    public static class cancelCompaction<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, cancelCompaction_args, Void> {
      public cancelCompaction() {
        super("cancelCompaction");
      }

      public cancelCompaction_args getEmptyArgsInstance() {
        return new cancelCompaction_args();
      }

      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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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 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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

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

    public static class createTable<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, createTable_args, Void> {
      public createTable() {
        super("createTable");
      }

      public createTable_args getEmptyArgsInstance() {
        return new createTable_args();
      }

      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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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 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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

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

    public static class deleteTable<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, deleteTable_args, Void> {
      public deleteTable() {
        super("deleteTable");
      }

      public deleteTable_args getEmptyArgsInstance() {
        return new deleteTable_args();
      }

      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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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 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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

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

    public static class deleteRows<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, deleteRows_args, Void> {
      public deleteRows() {
        super("deleteRows");
      }

      public deleteRows_args getEmptyArgsInstance() {
        return new deleteRows_args();
      }

      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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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 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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

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

    public static class exportTable<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, exportTable_args, Void> {
      public exportTable() {
        super("exportTable");
      }

      public exportTable_args getEmptyArgsInstance() {
        return new exportTable_args();
      }

      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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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 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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

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

    public static class flushTable<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, flushTable_args, Void> {
      public flushTable() {
        super("flushTable");
      }

      public flushTable_args getEmptyArgsInstance() {
        return new flushTable_args();
      }

      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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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 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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      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, java.util.List<DiskUsage>> {
      public getDiskUsage() {
        super("getDiskUsage");
      }

      public getDiskUsage_args getEmptyArgsInstance() {
        return new getDiskUsage_args();
      }

      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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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 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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      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, java.util.Map<java.lang.String,java.util.Set<java.lang.String>>> {
      public getLocalityGroups() {
        super("getLocalityGroups");
      }

      public getLocalityGroups_args getEmptyArgsInstance() {
        return new getLocalityGroups_args();
      }

      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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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 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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

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

    public static class getIteratorSetting<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getIteratorSetting_args, IteratorSetting> {
      public getIteratorSetting() {
        super("getIteratorSetting");
      }

      public getIteratorSetting_args getEmptyArgsInstance() {
        return new getIteratorSetting_args();
      }

      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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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 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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      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, java.nio.ByteBuffer> {
      public getMaxRow() {
        super("getMaxRow");
      }

      public getMaxRow_args getEmptyArgsInstance() {
        return new getMaxRow_args();
      }

      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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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 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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      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, java.util.Map<java.lang.String,java.lang.String>> {
      public getTableProperties() {
        super("getTableProperties");
      }

      public getTableProperties_args getEmptyArgsInstance() {
        return new getTableProperties_args();
      }

      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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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 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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

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

    public static class importDirectory<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, importDirectory_args, Void> {
      public importDirectory() {
        super("importDirectory");
      }

      public importDirectory_args getEmptyArgsInstance() {
        return new importDirectory_args();
      }

      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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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 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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

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

    public static class importTable<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, importTable_args, Void> {
      public importTable() {
        super("importTable");
      }

      public importTable_args getEmptyArgsInstance() {
        return new importTable_args();
      }

      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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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 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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      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, java.util.List<java.nio.ByteBuffer>> {
      public listSplits() {
        super("listSplits");
      }

      public listSplits_args getEmptyArgsInstance() {
        return new listSplits_args();
      }

      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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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 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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      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, java.util.Set<java.lang.String>> {
      public listTables() {
        super("listTables");
      }

      public listTables_args getEmptyArgsInstance() {
        return new listTables_args();
      }

      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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      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, java.util.Map<java.lang.String,java.util.Set<IteratorScope>>> {
      public listIterators() {
        super("listIterators");
      }

      public listIterators_args getEmptyArgsInstance() {
        return new listIterators_args();
      }

      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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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 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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      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, java.util.Map<java.lang.String,java.lang.Integer>> {
      public listConstraints() {
        super("listConstraints");
      }

      public listConstraints_args getEmptyArgsInstance() {
        return new listConstraints_args();
      }

      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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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 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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

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

    public static class mergeTablets<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, mergeTablets_args, Void> {
      public mergeTablets() {
        super("mergeTablets");
      }

      public mergeTablets_args getEmptyArgsInstance() {
        return new mergeTablets_args();
      }

      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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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 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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

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

    public static class offlineTable<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, offlineTable_args, Void> {
      public offlineTable() {
        super("offlineTable");
      }

      public offlineTable_args getEmptyArgsInstance() {
        return new offlineTable_args();
      }

      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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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 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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

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

    public static class onlineTable<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, onlineTable_args, Void> {
      public onlineTable() {
        super("onlineTable");
      }

      public onlineTable_args getEmptyArgsInstance() {
        return new onlineTable_args();
      }

      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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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 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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

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

    public static class removeConstraint<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, removeConstraint_args, Void> {
      public removeConstraint() {
        super("removeConstraint");
      }

      public removeConstraint_args getEmptyArgsInstance() {
        return new removeConstraint_args();
      }

      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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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 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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

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

    public static class removeIterator<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, removeIterator_args, Void> {
      public removeIterator() {
        super("removeIterator");
      }

      public removeIterator_args getEmptyArgsInstance() {
        return new removeIterator_args();
      }

      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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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 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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

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

    public static class removeTableProperty<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, removeTableProperty_args, Void> {
      public removeTableProperty() {
        super("removeTableProperty");
      }

      public removeTableProperty_args getEmptyArgsInstance() {
        return new removeTableProperty_args();
      }

      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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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 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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

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

    public static class renameTable<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, renameTable_args, Void> {
      public renameTable() {
        super("renameTable");
      }

      public renameTable_args getEmptyArgsInstance() {
        return new renameTable_args();
      }

      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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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 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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

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

    public static class setLocalityGroups<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, setLocalityGroups_args, Void> {
      public setLocalityGroups() {
        super("setLocalityGroups");
      }

      public setLocalityGroups_args getEmptyArgsInstance() {
        return new setLocalityGroups_args();
      }

      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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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 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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

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

    public static class setTableProperty<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, setTableProperty_args, Void> {
      public setTableProperty() {
        super("setTableProperty");
      }

      public setTableProperty_args getEmptyArgsInstance() {
        return new setTableProperty_args();
      }

      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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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 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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      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, java.util.Set<Range>> {
      public splitRangeByTablets() {
        super("splitRangeByTablets");
      }

      public splitRangeByTablets_args getEmptyArgsInstance() {
        return new splitRangeByTablets_args();
      }

      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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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 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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      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, java.lang.Boolean> {
      public tableExists() {
        super("tableExists");
      }

      public tableExists_args getEmptyArgsInstance() {
        return new tableExists_args();
      }

      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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      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, java.util.Map<java.lang.String,java.lang.String>> {
      public tableIdMap() {
        super("tableIdMap");
      }

      public tableIdMap_args getEmptyArgsInstance() {
        return new tableIdMap_args();
      }

      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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      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, java.lang.Boolean> {
      public testTableClassLoad() {
        super("testTableClassLoad");
      }

      public testTableClassLoad_args getEmptyArgsInstance() {
        return new testTableClassLoad_args();
      }

      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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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 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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

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

    public static class pingTabletServer<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, pingTabletServer_args, Void> {
      public pingTabletServer() {
        super("pingTabletServer");
      }

      public pingTabletServer_args getEmptyArgsInstance() {
        return new pingTabletServer_args();
      }

      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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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 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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      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, java.util.List<ActiveScan>> {
      public getActiveScans() {
        super("getActiveScans");
      }

      public getActiveScans_args getEmptyArgsInstance() {
        return new getActiveScans_args();
      }

      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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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 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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      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, java.util.List<ActiveCompaction>> {
      public getActiveCompactions() {
        super("getActiveCompactions");
      }

      public getActiveCompactions_args getEmptyArgsInstance() {
        return new getActiveCompactions_args();
      }

      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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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 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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      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, java.util.Map<java.lang.String,java.lang.String>> {
      public getSiteConfiguration() {
        super("getSiteConfiguration");
      }

      public getSiteConfiguration_args getEmptyArgsInstance() {
        return new getSiteConfiguration_args();
      }

      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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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 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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      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, java.util.Map<java.lang.String,java.lang.String>> {
      public getSystemConfiguration() {
        super("getSystemConfiguration");
      }

      public getSystemConfiguration_args getEmptyArgsInstance() {
        return new getSystemConfiguration_args();
      }

      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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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 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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      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, java.util.List<java.lang.String>> {
      public getTabletServers() {
        super("getTabletServers");
      }

      public getTabletServers_args getEmptyArgsInstance() {
        return new getTabletServers_args();
      }

      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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

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

    public static class removeProperty<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, removeProperty_args, Void> {
      public removeProperty() {
        super("removeProperty");
      }

      public removeProperty_args getEmptyArgsInstance() {
        return new removeProperty_args();
      }

      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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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 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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

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

    public static class setProperty<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, setProperty_args, Void> {
      public setProperty() {
        super("setProperty");
      }

      public setProperty_args getEmptyArgsInstance() {
        return new setProperty_args();
      }

      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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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 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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      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, java.lang.Boolean> {
      public testClassLoad() {
        super("testClassLoad");
      }

      public testClassLoad_args getEmptyArgsInstance() {
        return new testClassLoad_args();
      }

      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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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 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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      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, java.lang.Boolean> {
      public authenticateUser() {
        super("authenticateUser");
      }

      public authenticateUser_args getEmptyArgsInstance() {
        return new authenticateUser_args();
      }

      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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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 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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

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

    public static class changeUserAuthorizations<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, changeUserAuthorizations_args, Void> {
      public changeUserAuthorizations() {
        super("changeUserAuthorizations");
      }

      public changeUserAuthorizations_args getEmptyArgsInstance() {
        return new changeUserAuthorizations_args();
      }

      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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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 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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

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

    public static class changeLocalUserPassword<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, changeLocalUserPassword_args, Void> {
      public changeLocalUserPassword() {
        super("changeLocalUserPassword");
      }

      public changeLocalUserPassword_args getEmptyArgsInstance() {
        return new changeLocalUserPassword_args();
      }

      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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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 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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

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

    public static class createLocalUser<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, createLocalUser_args, Void> {
      public createLocalUser() {
        super("createLocalUser");
      }

      public createLocalUser_args getEmptyArgsInstance() {
        return new createLocalUser_args();
      }

      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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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 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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

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

    public static class dropLocalUser<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, dropLocalUser_args, Void> {
      public dropLocalUser() {
        super("dropLocalUser");
      }

      public dropLocalUser_args getEmptyArgsInstance() {
        return new dropLocalUser_args();
      }

      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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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 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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      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, java.util.List<java.nio.ByteBuffer>> {
      public getUserAuthorizations() {
        super("getUserAuthorizations");
      }

      public getUserAuthorizations_args getEmptyArgsInstance() {
        return new getUserAuthorizations_args();
      }

      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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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 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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

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

    public static class grantSystemPermission<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, grantSystemPermission_args, Void> {
      public grantSystemPermission() {
        super("grantSystemPermission");
      }

      public grantSystemPermission_args getEmptyArgsInstance() {
        return new grantSystemPermission_args();
      }

      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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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 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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

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

    public static class grantTablePermission<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, grantTablePermission_args, Void> {
      public grantTablePermission() {
        super("grantTablePermission");
      }

      public grantTablePermission_args getEmptyArgsInstance() {
        return new grantTablePermission_args();
      }

      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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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 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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      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, java.lang.Boolean> {
      public hasSystemPermission() {
        super("hasSystemPermission");
      }

      public hasSystemPermission_args getEmptyArgsInstance() {
        return new hasSystemPermission_args();
      }

      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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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 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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      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, java.lang.Boolean> {
      public hasTablePermission() {
        super("hasTablePermission");
      }

      public hasTablePermission_args getEmptyArgsInstance() {
        return new hasTablePermission_args();
      }

      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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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 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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      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, java.util.Set<java.lang.String>> {
      public listLocalUsers() {
        super("listLocalUsers");
      }

      public listLocalUsers_args getEmptyArgsInstance() {
        return new listLocalUsers_args();
      }

      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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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 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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

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

    public static class revokeSystemPermission<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, revokeSystemPermission_args, Void> {
      public revokeSystemPermission() {
        super("revokeSystemPermission");
      }

      public revokeSystemPermission_args getEmptyArgsInstance() {
        return new revokeSystemPermission_args();
      }

      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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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 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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

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

    public static class revokeTablePermission<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, revokeTablePermission_args, Void> {
      public revokeTablePermission() {
        super("revokeTablePermission");
      }

      public revokeTablePermission_args getEmptyArgsInstance() {
        return new revokeTablePermission_args();
      }

      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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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 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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

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

    public static class grantNamespacePermission<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, grantNamespacePermission_args, Void> {
      public grantNamespacePermission() {
        super("grantNamespacePermission");
      }

      public grantNamespacePermission_args getEmptyArgsInstance() {
        return new grantNamespacePermission_args();
      }

      public 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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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 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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, grantNamespacePermission_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws 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, java.lang.Boolean> {
      public hasNamespacePermission() {
        super("hasNamespacePermission");
      }

      public hasNamespacePermission_args getEmptyArgsInstance() {
        return new hasNamespacePermission_args();
      }

      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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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 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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, hasNamespacePermission_args args, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
        iface.hasNamespacePermission(args.login, args.user, args.namespaceName, args.perm,resultHandler);
      }
    }

    public static class revokeNamespacePermission<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, revokeNamespacePermission_args, Void> {
      public revokeNamespacePermission() {
        super("revokeNamespacePermission");
      }

      public revokeNamespacePermission_args getEmptyArgsInstance() {
        return new revokeNamespacePermission_args();
      }

      public 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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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 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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, revokeNamespacePermission_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws 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, java.lang.String> {
      public createBatchScanner() {
        super("createBatchScanner");
      }

      public createBatchScanner_args getEmptyArgsInstance() {
        return new createBatchScanner_args();
      }

      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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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 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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      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, java.lang.String> {
      public createScanner() {
        super("createScanner");
      }

      public createScanner_args getEmptyArgsInstance() {
        return new createScanner_args();
      }

      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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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 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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      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, java.lang.Boolean> {
      public hasNext() {
        super("hasNext");
      }

      public hasNext_args getEmptyArgsInstance() {
        return new hasNext_args();
      }

      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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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 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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

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

    public static class nextEntry<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, nextEntry_args, KeyValueAndPeek> {
      public nextEntry() {
        super("nextEntry");
      }

      public nextEntry_args getEmptyArgsInstance() {
        return new nextEntry_args();
      }

      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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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 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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

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

    public static class nextK<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, nextK_args, ScanResult> {
      public nextK() {
        super("nextK");
      }

      public nextK_args getEmptyArgsInstance() {
        return new nextK_args();
      }

      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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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 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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

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

    public static class closeScanner<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, closeScanner_args, Void> {
      public closeScanner() {
        super("closeScanner");
      }

      public closeScanner_args getEmptyArgsInstance() {
        return new closeScanner_args();
      }

      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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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 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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

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

    public static class updateAndFlush<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, updateAndFlush_args, Void> {
      public updateAndFlush() {
        super("updateAndFlush");
      }

      public updateAndFlush_args getEmptyArgsInstance() {
        return new updateAndFlush_args();
      }

      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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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 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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      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, java.lang.String> {
      public createWriter() {
        super("createWriter");
      }

      public createWriter_args getEmptyArgsInstance() {
        return new createWriter_args();
      }

      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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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 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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

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

    public static class update<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, update_args, Void> {
      public update() {
        super("update");
      }

      public update_args getEmptyArgsInstance() {
        return new update_args();
      }

      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 org.apache.thrift.async.AsyncMethodCallback<Void>() { 
          public void onComplete(Void o) {
          }
          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);
            }
          }
        };
      }

      protected boolean isOneway() {
        return true;
      }

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

    public static class flush<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, flush_args, Void> {
      public flush() {
        super("flush");
      }

      public flush_args getEmptyArgsInstance() {
        return new flush_args();
      }

      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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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 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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

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

    public static class closeWriter<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, closeWriter_args, Void> {
      public closeWriter() {
        super("closeWriter");
      }

      public closeWriter_args getEmptyArgsInstance() {
        return new closeWriter_args();
      }

      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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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 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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

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

    public static class updateRowConditionally<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, updateRowConditionally_args, ConditionalStatus> {
      public updateRowConditionally() {
        super("updateRowConditionally");
      }

      public updateRowConditionally_args getEmptyArgsInstance() {
        return new updateRowConditionally_args();
      }

      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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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 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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      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, java.lang.String> {
      public createConditionalWriter() {
        super("createConditionalWriter");
      }

      public createConditionalWriter_args getEmptyArgsInstance() {
        return new createConditionalWriter_args();
      }

      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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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 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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      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, java.util.Map<java.nio.ByteBuffer,ConditionalStatus>> {
      public updateRowsConditionally() {
        super("updateRowsConditionally");
      }

      public updateRowsConditionally_args getEmptyArgsInstance() {
        return new updateRowsConditionally_args();
      }

      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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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 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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

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

    public static class closeConditionalWriter<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, closeConditionalWriter_args, Void> {
      public closeConditionalWriter() {
        super("closeConditionalWriter");
      }

      public closeConditionalWriter_args getEmptyArgsInstance() {
        return new closeConditionalWriter_args();
      }

      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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

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

    public static class getRowRange<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getRowRange_args, Range> {
      public getRowRange() {
        super("getRowRange");
      }

      public getRowRange_args getEmptyArgsInstance() {
        return new getRowRange_args();
      }

      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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

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

    public static class getFollowing<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getFollowing_args, Key> {
      public getFollowing() {
        super("getFollowing");
      }

      public getFollowing_args getEmptyArgsInstance() {
        return new getFollowing_args();
      }

      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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      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, java.lang.String> {
      public systemNamespace() {
        super("systemNamespace");
      }

      public systemNamespace_args getEmptyArgsInstance() {
        return new systemNamespace_args();
      }

      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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, systemNamespace_args args, org.apache.thrift.async.AsyncMethodCallback<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, java.lang.String> {
      public defaultNamespace() {
        super("defaultNamespace");
      }

      public defaultNamespace_args getEmptyArgsInstance() {
        return new defaultNamespace_args();
      }

      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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, defaultNamespace_args args, org.apache.thrift.async.AsyncMethodCallback<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, java.util.List<java.lang.String>> {
      public listNamespaces() {
        super("listNamespaces");
      }

      public listNamespaces_args getEmptyArgsInstance() {
        return new listNamespaces_args();
      }

      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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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 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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, listNamespaces_args args, org.apache.thrift.async.AsyncMethodCallback<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, java.lang.Boolean> {
      public namespaceExists() {
        super("namespaceExists");
      }

      public namespaceExists_args getEmptyArgsInstance() {
        return new namespaceExists_args();
      }

      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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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 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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, namespaceExists_args args, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
        iface.namespaceExists(args.login, args.namespaceName,resultHandler);
      }
    }

    public static class createNamespace<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, createNamespace_args, Void> {
      public createNamespace() {
        super("createNamespace");
      }

      public createNamespace_args getEmptyArgsInstance() {
        return new createNamespace_args();
      }

      public 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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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 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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, createNamespace_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
        iface.createNamespace(args.login, args.namespaceName,resultHandler);
      }
    }

    public static class deleteNamespace<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, deleteNamespace_args, Void> {
      public deleteNamespace() {
        super("deleteNamespace");
      }

      public deleteNamespace_args getEmptyArgsInstance() {
        return new deleteNamespace_args();
      }

      public 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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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 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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, deleteNamespace_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
        iface.deleteNamespace(args.login, args.namespaceName,resultHandler);
      }
    }

    public static class renameNamespace<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, renameNamespace_args, Void> {
      public renameNamespace() {
        super("renameNamespace");
      }

      public renameNamespace_args getEmptyArgsInstance() {
        return new renameNamespace_args();
      }

      public 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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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 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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, renameNamespace_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
        iface.renameNamespace(args.login, args.oldNamespaceName, args.newNamespaceName,resultHandler);
      }
    }

    public static class setNamespaceProperty<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, setNamespaceProperty_args, Void> {
      public setNamespaceProperty() {
        super("setNamespaceProperty");
      }

      public setNamespaceProperty_args getEmptyArgsInstance() {
        return new setNamespaceProperty_args();
      }

      public 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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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 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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, setNamespaceProperty_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
        iface.setNamespaceProperty(args.login, args.namespaceName, args.property, args.value,resultHandler);
      }
    }

    public static class removeNamespaceProperty<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, removeNamespaceProperty_args, Void> {
      public removeNamespaceProperty() {
        super("removeNamespaceProperty");
      }

      public removeNamespaceProperty_args getEmptyArgsInstance() {
        return new removeNamespaceProperty_args();
      }

      public 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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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 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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, removeNamespaceProperty_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws 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, java.util.Map<java.lang.String,java.lang.String>> {
      public getNamespaceProperties() {
        super("getNamespaceProperties");
      }

      public getNamespaceProperties_args getEmptyArgsInstance() {
        return new getNamespaceProperties_args();
      }

      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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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 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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, getNamespaceProperties_args args, org.apache.thrift.async.AsyncMethodCallback<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, java.util.Map<java.lang.String,java.lang.String>> {
      public namespaceIdMap() {
        super("namespaceIdMap");
      }

      public namespaceIdMap_args getEmptyArgsInstance() {
        return new namespaceIdMap_args();
      }

      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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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 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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, namespaceIdMap_args args, org.apache.thrift.async.AsyncMethodCallback<java.util.Map<java.lang.String,java.lang.String>> resultHandler) throws org.apache.thrift.TException {
        iface.namespaceIdMap(args.login,resultHandler);
      }
    }

    public static class attachNamespaceIterator<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, attachNamespaceIterator_args, Void> {
      public attachNamespaceIterator() {
        super("attachNamespaceIterator");
      }

      public attachNamespaceIterator_args getEmptyArgsInstance() {
        return new attachNamespaceIterator_args();
      }

      public 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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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 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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, attachNamespaceIterator_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
        iface.attachNamespaceIterator(args.login, args.namespaceName, args.setting, args.scopes,resultHandler);
      }
    }

    public static class removeNamespaceIterator<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, removeNamespaceIterator_args, Void> {
      public removeNamespaceIterator() {
        super("removeNamespaceIterator");
      }

      public removeNamespaceIterator_args getEmptyArgsInstance() {
        return new removeNamespaceIterator_args();
      }

      public 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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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 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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, removeNamespaceIterator_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
        iface.removeNamespaceIterator(args.login, args.namespaceName, args.name, args.scopes,resultHandler);
      }
    }

    public static class getNamespaceIteratorSetting<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getNamespaceIteratorSetting_args, IteratorSetting> {
      public getNamespaceIteratorSetting() {
        super("getNamespaceIteratorSetting");
      }

      public getNamespaceIteratorSetting_args getEmptyArgsInstance() {
        return new getNamespaceIteratorSetting_args();
      }

      public 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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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 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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, getNamespaceIteratorSetting_args args, org.apache.thrift.async.AsyncMethodCallback<IteratorSetting> resultHandler) throws 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, java.util.Map<java.lang.String,java.util.Set<IteratorScope>>> {
      public listNamespaceIterators() {
        super("listNamespaceIterators");
      }

      public listNamespaceIterators_args getEmptyArgsInstance() {
        return new listNamespaceIterators_args();
      }

      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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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 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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, listNamespaceIterators_args args, org.apache.thrift.async.AsyncMethodCallback<java.util.Map<java.lang.String,java.util.Set<IteratorScope>>> resultHandler) throws org.apache.thrift.TException {
        iface.listNamespaceIterators(args.login, args.namespaceName,resultHandler);
      }
    }

    public static class checkNamespaceIteratorConflicts<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, checkNamespaceIteratorConflicts_args, Void> {
      public checkNamespaceIteratorConflicts() {
        super("checkNamespaceIteratorConflicts");
      }

      public checkNamespaceIteratorConflicts_args getEmptyArgsInstance() {
        return new checkNamespaceIteratorConflicts_args();
      }

      public 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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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 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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, checkNamespaceIteratorConflicts_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws 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, java.lang.Integer> {
      public addNamespaceConstraint() {
        super("addNamespaceConstraint");
      }

      public addNamespaceConstraint_args getEmptyArgsInstance() {
        return new addNamespaceConstraint_args();
      }

      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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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 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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, addNamespaceConstraint_args args, org.apache.thrift.async.AsyncMethodCallback<java.lang.Integer> resultHandler) throws org.apache.thrift.TException {
        iface.addNamespaceConstraint(args.login, args.namespaceName, args.constraintClassName,resultHandler);
      }
    }

    public static class removeNamespaceConstraint<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, removeNamespaceConstraint_args, Void> {
      public removeNamespaceConstraint() {
        super("removeNamespaceConstraint");
      }

      public removeNamespaceConstraint_args getEmptyArgsInstance() {
        return new removeNamespaceConstraint_args();
      }

      public 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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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 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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, removeNamespaceConstraint_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws 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, java.util.Map<java.lang.String,java.lang.Integer>> {
      public listNamespaceConstraints() {
        super("listNamespaceConstraints");
      }

      public listNamespaceConstraints_args getEmptyArgsInstance() {
        return new listNamespaceConstraints_args();
      }

      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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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 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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, listNamespaceConstraints_args args, org.apache.thrift.async.AsyncMethodCallback<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, java.lang.Boolean> {
      public testNamespaceClassLoad() {
        super("testNamespaceClassLoad");
      }

      public testNamespaceClassLoad_args getEmptyArgsInstance() {
        return new testNamespaceClassLoad_args();
      }

      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 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);
            } 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);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            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 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.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);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, testNamespaceClassLoad_args args, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
        iface.testNamespaceClassLoad(args.login, args.namespaceName, args.className, args.asTypeName,resultHandler);
      }
    }

  }

  public static class login_args implements org.apache.thrift.TBase<login_args, login_args._Fields>, java.io.Serializable, Cloneable, Comparable<login_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("login_args");

    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 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 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 java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // PRINCIPAL
            return PRINCIPAL;
          case 2: // LOGIN_PROPERTIES
            return LOGIN_PROPERTIES;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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 = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(login_args.class, metaDataMap);
    }

    public login_args() {
    }

    public login_args(
      java.lang.String principal,
      java.util.Map<java.lang.String,java.lang.String> loginProperties)
    {
      this();
      this.principal = principal;
      this.loginProperties = loginProperties;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public login_args(login_args other) {
      if (other.isSetPrincipal()) {
        this.principal = other.principal;
      }
      if (other.isSetLoginProperties()) {
        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;
      }
    }

    public login_args deepCopy() {
      return new login_args(this);
    }

    @Override
    public void clear() {
      this.principal = null;
      this.loginProperties = null;
    }

    public java.lang.String getPrincipal() {
      return this.principal;
    }

    public login_args setPrincipal(java.lang.String principal) {
      this.principal = principal;
      return this;
    }

    public void unsetPrincipal() {
      this.principal = null;
    }

    /** Returns true if field principal is set (has been assigned a value) and false otherwise */
    public boolean isSetPrincipal() {
      return this.principal != null;
    }

    public void setPrincipalIsSet(boolean value) {
      if (!value) {
        this.principal = null;
      }
    }

    public int getLoginPropertiesSize() {
      return (this.loginProperties == null) ? 0 : this.loginProperties.size();
    }

    public void putToLoginProperties(java.lang.String key, java.lang.String val) {
      if (this.loginProperties == null) {
        this.loginProperties = new java.util.HashMap<java.lang.String,java.lang.String>();
      }
      this.loginProperties.put(key, val);
    }

    public java.util.Map<java.lang.String,java.lang.String> getLoginProperties() {
      return this.loginProperties;
    }

    public login_args setLoginProperties(java.util.Map<java.lang.String,java.lang.String> loginProperties) {
      this.loginProperties = loginProperties;
      return this;
    }

    public void unsetLoginProperties() {
      this.loginProperties = null;
    }

    /** Returns true if field loginProperties is set (has been assigned a value) and false otherwise */
    public boolean isSetLoginProperties() {
      return this.loginProperties != null;
    }

    public void setLoginPropertiesIsSet(boolean value) {
      if (!value) {
        this.loginProperties = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case PRINCIPAL:
        if (value == null) {
          unsetPrincipal();
        } else {
          setPrincipal((java.lang.String)value);
        }
        break;

      case LOGIN_PROPERTIES:
        if (value == null) {
          unsetLoginProperties();
        } else {
          setLoginProperties((java.util.Map<java.lang.String,java.lang.String>)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case PRINCIPAL:
        return getPrincipal();

      case LOGIN_PROPERTIES:
        return getLoginProperties();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case PRINCIPAL:
        return isSetPrincipal();
      case LOGIN_PROPERTIES:
        return isSetLoginProperties();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof login_args)
        return this.equals((login_args)that);
      return false;
    }

    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();
      if (this_present_principal || that_present_principal) {
        if (!(this_present_principal && that_present_principal))
          return false;
        if (!this.principal.equals(that.principal))
          return false;
      }

      boolean this_present_loginProperties = true && this.isSetLoginProperties();
      boolean that_present_loginProperties = true && that.isSetLoginProperties();
      if (this_present_loginProperties || that_present_loginProperties) {
        if (!(this_present_loginProperties && that_present_loginProperties))
          return false;
        if (!this.loginProperties.equals(that.loginProperties))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetPrincipal()) ? 131071 : 524287);
      if (isSetPrincipal())
        hashCode = hashCode * 8191 + principal.hashCode();

      hashCode = hashCode * 8191 + ((isSetLoginProperties()) ? 131071 : 524287);
      if (isSetLoginProperties())
        hashCode = hashCode * 8191 + loginProperties.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(login_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetPrincipal()).compareTo(other.isSetPrincipal());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetPrincipal()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.principal, other.principal);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetLoginProperties()).compareTo(other.isSetLoginProperties());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLoginProperties()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.loginProperties, other.loginProperties);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("login_args(");
      boolean first = true;

      sb.append("principal:");
      if (this.principal == null) {
        sb.append("null");
      } else {
        sb.append(this.principal);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("loginProperties:");
      if (this.loginProperties == null) {
        sb.append("null");
      } else {
        sb.append(this.loginProperties);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class login_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public login_argsStandardScheme getScheme() {
        return new login_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // PRINCIPAL
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.principal = iprot.readString();
                struct.setPrincipalIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // LOGIN_PROPERTIES
              if (schemeField.type == org.apache.thrift.protocol.TType.MAP) {
                {
                  org.apache.thrift.protocol.TMap _map164 = iprot.readMapBegin();
                  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();
                    _val166 = iprot.readString();
                    struct.loginProperties.put(_key165, _val166);
                  }
                  iprot.readMapEnd();
                }
                struct.setLoginPropertiesIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, login_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.principal != null) {
          oprot.writeFieldBegin(PRINCIPAL_FIELD_DESC);
          oprot.writeString(struct.principal);
          oprot.writeFieldEnd();
        }
        if (struct.loginProperties != null) {
          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 (java.util.Map.Entry<java.lang.String, java.lang.String> _iter168 : struct.loginProperties.entrySet())
            {
              oprot.writeString(_iter168.getKey());
              oprot.writeString(_iter168.getValue());
            }
            oprot.writeMapEnd();
          }
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    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 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 {
        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);
        }
        if (struct.isSetLoginProperties()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetPrincipal()) {
          oprot.writeString(struct.principal);
        }
        if (struct.isSetLoginProperties()) {
          {
            oprot.writeI32(struct.loginProperties.size());
            for (java.util.Map.Entry<java.lang.String, java.lang.String> _iter169 : struct.loginProperties.entrySet())
            {
              oprot.writeString(_iter169.getKey());
              oprot.writeString(_iter169.getValue());
            }
          }
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, login_args struct) throws org.apache.thrift.TException {
        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);
        }
        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 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();
              _val172 = iprot.readString();
              struct.loginProperties.put(_key171, _val172);
            }
          }
          struct.setLoginPropertiesIsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("login_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.STRING, (short)0);
    private static final 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 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 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. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      OUCH2((short)1, "ouch2");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // OUCH2
            return OUCH2;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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);
    }

    public login_result() {
    }

    public login_result(
      java.nio.ByteBuffer success,
      AccumuloSecurityException ouch2)
    {
      this();
      this.success = org.apache.thrift.TBaseHelper.copyBinary(success);
      this.ouch2 = ouch2;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public login_result(login_result other) {
      if (other.isSetSuccess()) {
        this.success = org.apache.thrift.TBaseHelper.copyBinary(other.success);
      }
      if (other.isSetOuch2()) {
        this.ouch2 = new AccumuloSecurityException(other.ouch2);
      }
    }

    public login_result deepCopy() {
      return new login_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ouch2 = null;
    }

    public byte[] getSuccess() {
      setSuccess(org.apache.thrift.TBaseHelper.rightSize(success));
      return success == null ? null : success.array();
    }

    public java.nio.ByteBuffer bufferForSuccess() {
      return org.apache.thrift.TBaseHelper.copyBinary(success);
    }

    public login_result setSuccess(byte[] success) {
      this.success = success == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(success.clone());
      return this;
    }

    public login_result setSuccess(java.nio.ByteBuffer success) {
      this.success = org.apache.thrift.TBaseHelper.copyBinary(success);
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return this.success != null;
    }

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public AccumuloSecurityException getOuch2() {
      return this.ouch2;
    }

    public login_result setOuch2(AccumuloSecurityException ouch2) {
      this.ouch2 = ouch2;
      return this;
    }

    public void unsetOuch2() {
      this.ouch2 = null;
    }

    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch2() {
      return this.ouch2 != null;
    }

    public void setOuch2IsSet(boolean value) {
      if (!value) {
        this.ouch2 = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          if (value instanceof byte[]) {
            setSuccess((byte[])value);
          } else {
            setSuccess((java.nio.ByteBuffer)value);
          }
        }
        break;

      case OUCH2:
        if (value == null) {
          unsetOuch2();
        } else {
          setOuch2((AccumuloSecurityException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case OUCH2:
        return getOuch2();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case OUCH2:
        return isSetOuch2();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof login_result)
        return this.equals((login_result)that);
      return false;
    }

    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();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ouch2 = true && this.isSetOuch2();
      boolean that_present_ouch2 = true && that.isSetOuch2();
      if (this_present_ouch2 || that_present_ouch2) {
        if (!(this_present_ouch2 && that_present_ouch2))
          return false;
        if (!this.ouch2.equals(that.ouch2))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
      if (isSetSuccess())
        hashCode = hashCode * 8191 + success.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
      if (isSetOuch2())
        hashCode = hashCode * 8191 + ouch2.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(login_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch2()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("login_result(");
      boolean first = true;

      sb.append("success:");
      if (this.success == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.success, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch2:");
      if (this.ouch2 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch2);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class login_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public login_resultStandardScheme getScheme() {
        return new login_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.success = iprot.readBinary();
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // OUCH2
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch2 = new AccumuloSecurityException();
                struct.ouch2.read(iprot);
                struct.setOuch2IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, login_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          oprot.writeBinary(struct.success);
          oprot.writeFieldEnd();
        }
        if (struct.ouch2 != null) {
          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
          struct.ouch2.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    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 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 {
        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);
        }
        if (struct.isSetOuch2()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetSuccess()) {
          oprot.writeBinary(struct.success);
        }
        if (struct.isSetOuch2()) {
          struct.ouch2.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, login_result struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.ouch2 = new AccumuloSecurityException();
          struct.ouch2.read(iprot);
          struct.setOuch2IsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("addConstraint_args");

    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField 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 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 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 {
      LOGIN((short)1, "login"),
      TABLE_NAME((short)2, "tableName"),
      CONSTRAINT_CLASS_NAME((short)3, "constraintClassName");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // LOGIN
            return LOGIN;
          case 2: // TABLE_NAME
            return TABLE_NAME;
          case 3: // CONSTRAINT_CLASS_NAME
            return CONSTRAINT_CLASS_NAME;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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 = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(addConstraint_args.class, metaDataMap);
    }

    public addConstraint_args() {
    }

    public addConstraint_args(
      java.nio.ByteBuffer login,
      java.lang.String tableName,
      java.lang.String constraintClassName)
    {
      this();
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      this.tableName = tableName;
      this.constraintClassName = constraintClassName;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public addConstraint_args(addConstraint_args other) {
      if (other.isSetLogin()) {
        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
      }
      if (other.isSetTableName()) {
        this.tableName = other.tableName;
      }
      if (other.isSetConstraintClassName()) {
        this.constraintClassName = other.constraintClassName;
      }
    }

    public addConstraint_args deepCopy() {
      return new addConstraint_args(this);
    }

    @Override
    public void clear() {
      this.login = null;
      this.tableName = null;
      this.constraintClassName = null;
    }

    public byte[] getLogin() {
      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
      return login == null ? null : login.array();
    }

    public java.nio.ByteBuffer bufferForLogin() {
      return org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    public addConstraint_args setLogin(byte[] login) {
      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
      return this;
    }

    public addConstraint_args setLogin(java.nio.ByteBuffer login) {
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      return this;
    }

    public void unsetLogin() {
      this.login = null;
    }

    /** Returns true if field login is set (has been assigned a value) and false otherwise */
    public boolean isSetLogin() {
      return this.login != null;
    }

    public void setLoginIsSet(boolean value) {
      if (!value) {
        this.login = null;
      }
    }

    public java.lang.String getTableName() {
      return this.tableName;
    }

    public addConstraint_args setTableName(java.lang.String tableName) {
      this.tableName = tableName;
      return this;
    }

    public void unsetTableName() {
      this.tableName = null;
    }

    /** Returns true if field tableName is set (has been assigned a value) and false otherwise */
    public boolean isSetTableName() {
      return this.tableName != null;
    }

    public void setTableNameIsSet(boolean value) {
      if (!value) {
        this.tableName = null;
      }
    }

    public java.lang.String getConstraintClassName() {
      return this.constraintClassName;
    }

    public addConstraint_args setConstraintClassName(java.lang.String constraintClassName) {
      this.constraintClassName = constraintClassName;
      return this;
    }

    public void unsetConstraintClassName() {
      this.constraintClassName = null;
    }

    /** Returns true if field constraintClassName is set (has been assigned a value) and false otherwise */
    public boolean isSetConstraintClassName() {
      return this.constraintClassName != null;
    }

    public void setConstraintClassNameIsSet(boolean value) {
      if (!value) {
        this.constraintClassName = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case LOGIN:
        if (value == null) {
          unsetLogin();
        } else {
          if (value instanceof byte[]) {
            setLogin((byte[])value);
          } else {
            setLogin((java.nio.ByteBuffer)value);
          }
        }
        break;

      case TABLE_NAME:
        if (value == null) {
          unsetTableName();
        } else {
          setTableName((java.lang.String)value);
        }
        break;

      case CONSTRAINT_CLASS_NAME:
        if (value == null) {
          unsetConstraintClassName();
        } else {
          setConstraintClassName((java.lang.String)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case LOGIN:
        return getLogin();

      case TABLE_NAME:
        return getTableName();

      case CONSTRAINT_CLASS_NAME:
        return getConstraintClassName();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case LOGIN:
        return isSetLogin();
      case TABLE_NAME:
        return isSetTableName();
      case CONSTRAINT_CLASS_NAME:
        return isSetConstraintClassName();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof addConstraint_args)
        return this.equals((addConstraint_args)that);
      return false;
    }

    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();
      if (this_present_login || that_present_login) {
        if (!(this_present_login && that_present_login))
          return false;
        if (!this.login.equals(that.login))
          return false;
      }

      boolean this_present_tableName = true && this.isSetTableName();
      boolean that_present_tableName = true && that.isSetTableName();
      if (this_present_tableName || that_present_tableName) {
        if (!(this_present_tableName && that_present_tableName))
          return false;
        if (!this.tableName.equals(that.tableName))
          return false;
      }

      boolean this_present_constraintClassName = true && this.isSetConstraintClassName();
      boolean that_present_constraintClassName = true && that.isSetConstraintClassName();
      if (this_present_constraintClassName || that_present_constraintClassName) {
        if (!(this_present_constraintClassName && that_present_constraintClassName))
          return false;
        if (!this.constraintClassName.equals(that.constraintClassName))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
      if (isSetLogin())
        hashCode = hashCode * 8191 + login.hashCode();

      hashCode = hashCode * 8191 + ((isSetTableName()) ? 131071 : 524287);
      if (isSetTableName())
        hashCode = hashCode * 8191 + tableName.hashCode();

      hashCode = hashCode * 8191 + ((isSetConstraintClassName()) ? 131071 : 524287);
      if (isSetConstraintClassName())
        hashCode = hashCode * 8191 + constraintClassName.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(addConstraint_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLogin()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetTableName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.tableName, other.tableName);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetConstraintClassName()).compareTo(other.isSetConstraintClassName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetConstraintClassName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.constraintClassName, other.constraintClassName);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("addConstraint_args(");
      boolean first = true;

      sb.append("login:");
      if (this.login == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.login, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("tableName:");
      if (this.tableName == null) {
        sb.append("null");
      } else {
        sb.append(this.tableName);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("constraintClassName:");
      if (this.constraintClassName == null) {
        sb.append("null");
      } else {
        sb.append(this.constraintClassName);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class addConstraint_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public addConstraint_argsStandardScheme getScheme() {
        return new addConstraint_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // LOGIN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.login = iprot.readBinary();
                struct.setLoginIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // TABLE_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.tableName = iprot.readString();
                struct.setTableNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // CONSTRAINT_CLASS_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.constraintClassName = iprot.readString();
                struct.setConstraintClassNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, addConstraint_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.login != null) {
          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
          oprot.writeBinary(struct.login);
          oprot.writeFieldEnd();
        }
        if (struct.tableName != null) {
          oprot.writeFieldBegin(TABLE_NAME_FIELD_DESC);
          oprot.writeString(struct.tableName);
          oprot.writeFieldEnd();
        }
        if (struct.constraintClassName != null) {
          oprot.writeFieldBegin(CONSTRAINT_CLASS_NAME_FIELD_DESC);
          oprot.writeString(struct.constraintClassName);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class addConstraint_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public addConstraint_argsTupleScheme getScheme() {
        return new addConstraint_argsTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetTableName()) {
          optionals.set(1);
        }
        if (struct.isSetConstraintClassName()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetLogin()) {
          oprot.writeBinary(struct.login);
        }
        if (struct.isSetTableName()) {
          oprot.writeString(struct.tableName);
        }
        if (struct.isSetConstraintClassName()) {
          oprot.writeString(struct.constraintClassName);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, addConstraint_args struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.tableName = iprot.readString();
          struct.setTableNameIsSet(true);
        }
        if (incoming.get(2)) {
          struct.constraintClassName = iprot.readString();
          struct.setConstraintClassNameIsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("addConstraint_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.I32, (short)0);
    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField OUCH3_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch3", org.apache.thrift.protocol.TType.STRUCT, (short)3);

    private static final 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
    public AccumuloSecurityException ouch2; // required
    public TableNotFoundException ouch3; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      OUCH1((short)1, "ouch1"),
      OUCH2((short)2, "ouch2"),
      OUCH3((short)3, "ouch3");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // OUCH1
            return OUCH1;
          case 2: // OUCH2
            return OUCH2;
          case 3: // OUCH3
            return OUCH3;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __SUCCESS_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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.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.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);
    }

    public addConstraint_result() {
    }

    public addConstraint_result(
      int success,
      AccumuloException ouch1,
      AccumuloSecurityException ouch2,
      TableNotFoundException ouch3)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
      this.ouch1 = ouch1;
      this.ouch2 = ouch2;
      this.ouch3 = ouch3;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public addConstraint_result(addConstraint_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
      if (other.isSetOuch1()) {
        this.ouch1 = new AccumuloException(other.ouch1);
      }
      if (other.isSetOuch2()) {
        this.ouch2 = new AccumuloSecurityException(other.ouch2);
      }
      if (other.isSetOuch3()) {
        this.ouch3 = new TableNotFoundException(other.ouch3);
      }
    }

    public addConstraint_result deepCopy() {
      return new addConstraint_result(this);
    }

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = 0;
      this.ouch1 = null;
      this.ouch2 = null;
      this.ouch3 = null;
    }

    public int getSuccess() {
      return this.success;
    }

    public addConstraint_result setSuccess(int success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

    public void unsetSuccess() {
      __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 org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    public void setSuccessIsSet(boolean value) {
      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
    }

    public AccumuloException getOuch1() {
      return this.ouch1;
    }

    public addConstraint_result setOuch1(AccumuloException ouch1) {
      this.ouch1 = ouch1;
      return this;
    }

    public void unsetOuch1() {
      this.ouch1 = null;
    }

    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch1() {
      return this.ouch1 != null;
    }

    public void setOuch1IsSet(boolean value) {
      if (!value) {
        this.ouch1 = null;
      }
    }

    public AccumuloSecurityException getOuch2() {
      return this.ouch2;
    }

    public addConstraint_result setOuch2(AccumuloSecurityException ouch2) {
      this.ouch2 = ouch2;
      return this;
    }

    public void unsetOuch2() {
      this.ouch2 = null;
    }

    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch2() {
      return this.ouch2 != null;
    }

    public void setOuch2IsSet(boolean value) {
      if (!value) {
        this.ouch2 = null;
      }
    }

    public TableNotFoundException getOuch3() {
      return this.ouch3;
    }

    public addConstraint_result setOuch3(TableNotFoundException ouch3) {
      this.ouch3 = ouch3;
      return this;
    }

    public void unsetOuch3() {
      this.ouch3 = null;
    }

    /** Returns true if field ouch3 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch3() {
      return this.ouch3 != null;
    }

    public void setOuch3IsSet(boolean value) {
      if (!value) {
        this.ouch3 = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.lang.Integer)value);
        }
        break;

      case OUCH1:
        if (value == null) {
          unsetOuch1();
        } else {
          setOuch1((AccumuloException)value);
        }
        break;

      case OUCH2:
        if (value == null) {
          unsetOuch2();
        } else {
          setOuch2((AccumuloSecurityException)value);
        }
        break;

      case OUCH3:
        if (value == null) {
          unsetOuch3();
        } else {
          setOuch3((TableNotFoundException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case OUCH1:
        return getOuch1();

      case OUCH2:
        return getOuch2();

      case OUCH3:
        return getOuch3();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case OUCH1:
        return isSetOuch1();
      case OUCH2:
        return isSetOuch2();
      case OUCH3:
        return isSetOuch3();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof addConstraint_result)
        return this.equals((addConstraint_result)that);
      return false;
    }

    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;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      boolean this_present_ouch1 = true && this.isSetOuch1();
      boolean that_present_ouch1 = true && that.isSetOuch1();
      if (this_present_ouch1 || that_present_ouch1) {
        if (!(this_present_ouch1 && that_present_ouch1))
          return false;
        if (!this.ouch1.equals(that.ouch1))
          return false;
      }

      boolean this_present_ouch2 = true && this.isSetOuch2();
      boolean that_present_ouch2 = true && that.isSetOuch2();
      if (this_present_ouch2 || that_present_ouch2) {
        if (!(this_present_ouch2 && that_present_ouch2))
          return false;
        if (!this.ouch2.equals(that.ouch2))
          return false;
      }

      boolean this_present_ouch3 = true && this.isSetOuch3();
      boolean that_present_ouch3 = true && that.isSetOuch3();
      if (this_present_ouch3 || that_present_ouch3) {
        if (!(this_present_ouch3 && that_present_ouch3))
          return false;
        if (!this.ouch3.equals(that.ouch3))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + success;

      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
      if (isSetOuch1())
        hashCode = hashCode * 8191 + ouch1.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
      if (isSetOuch2())
        hashCode = hashCode * 8191 + ouch2.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
      if (isSetOuch3())
        hashCode = hashCode * 8191 + ouch3.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(addConstraint_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch1()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch2()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch3()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch3, other.ouch3);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("addConstraint_result(");
      boolean first = true;

      sb.append("success:");
      sb.append(this.success);
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch1:");
      if (this.ouch1 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch1);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch2:");
      if (this.ouch2 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch2);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch3:");
      if (this.ouch3 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch3);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, 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;
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class addConstraint_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public addConstraint_resultStandardScheme getScheme() {
        return new addConstraint_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.success = iprot.readI32();
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // OUCH1
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch1 = new AccumuloException();
                struct.ouch1.read(iprot);
                struct.setOuch1IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OUCH2
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch2 = new AccumuloSecurityException();
                struct.ouch2.read(iprot);
                struct.setOuch2IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // OUCH3
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch3 = new TableNotFoundException();
                struct.ouch3.read(iprot);
                struct.setOuch3IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, addConstraint_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.isSetSuccess()) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          oprot.writeI32(struct.success);
          oprot.writeFieldEnd();
        }
        if (struct.ouch1 != null) {
          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
          struct.ouch1.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch2 != null) {
          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
          struct.ouch2.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch3 != null) {
          oprot.writeFieldBegin(OUCH3_FIELD_DESC);
          struct.ouch3.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class addConstraint_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public addConstraint_resultTupleScheme getScheme() {
        return new addConstraint_resultTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetOuch1()) {
          optionals.set(1);
        }
        if (struct.isSetOuch2()) {
          optionals.set(2);
        }
        if (struct.isSetOuch3()) {
          optionals.set(3);
        }
        oprot.writeBitSet(optionals, 4);
        if (struct.isSetSuccess()) {
          oprot.writeI32(struct.success);
        }
        if (struct.isSetOuch1()) {
          struct.ouch1.write(oprot);
        }
        if (struct.isSetOuch2()) {
          struct.ouch2.write(oprot);
        }
        if (struct.isSetOuch3()) {
          struct.ouch3.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, addConstraint_result struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.ouch1 = new AccumuloException();
          struct.ouch1.read(iprot);
          struct.setOuch1IsSet(true);
        }
        if (incoming.get(2)) {
          struct.ouch2 = new AccumuloSecurityException();
          struct.ouch2.read(iprot);
          struct.setOuch2IsSet(true);
        }
        if (incoming.get(3)) {
          struct.ouch3 = new TableNotFoundException();
          struct.ouch3.read(iprot);
          struct.setOuch3IsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("addSplits_args");

    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField 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 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 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 {
      LOGIN((short)1, "login"),
      TABLE_NAME((short)2, "tableName"),
      SPLITS((short)3, "splits");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // LOGIN
            return LOGIN;
          case 2: // TABLE_NAME
            return TABLE_NAME;
          case 3: // SPLITS
            return SPLITS;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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 = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(addSplits_args.class, metaDataMap);
    }

    public addSplits_args() {
    }

    public addSplits_args(
      java.nio.ByteBuffer login,
      java.lang.String tableName,
      java.util.Set<java.nio.ByteBuffer> splits)
    {
      this();
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      this.tableName = tableName;
      this.splits = splits;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public addSplits_args(addSplits_args other) {
      if (other.isSetLogin()) {
        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
      }
      if (other.isSetTableName()) {
        this.tableName = other.tableName;
      }
      if (other.isSetSplits()) {
        java.util.Set<java.nio.ByteBuffer> __this__splits = new java.util.HashSet<java.nio.ByteBuffer>(other.splits);
        this.splits = __this__splits;
      }
    }

    public addSplits_args deepCopy() {
      return new addSplits_args(this);
    }

    @Override
    public void clear() {
      this.login = null;
      this.tableName = null;
      this.splits = null;
    }

    public byte[] getLogin() {
      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
      return login == null ? null : login.array();
    }

    public java.nio.ByteBuffer bufferForLogin() {
      return org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    public addSplits_args setLogin(byte[] login) {
      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
      return this;
    }

    public addSplits_args setLogin(java.nio.ByteBuffer login) {
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      return this;
    }

    public void unsetLogin() {
      this.login = null;
    }

    /** Returns true if field login is set (has been assigned a value) and false otherwise */
    public boolean isSetLogin() {
      return this.login != null;
    }

    public void setLoginIsSet(boolean value) {
      if (!value) {
        this.login = null;
      }
    }

    public java.lang.String getTableName() {
      return this.tableName;
    }

    public addSplits_args setTableName(java.lang.String tableName) {
      this.tableName = tableName;
      return this;
    }

    public void unsetTableName() {
      this.tableName = null;
    }

    /** Returns true if field tableName is set (has been assigned a value) and false otherwise */
    public boolean isSetTableName() {
      return this.tableName != null;
    }

    public void setTableNameIsSet(boolean value) {
      if (!value) {
        this.tableName = null;
      }
    }

    public int getSplitsSize() {
      return (this.splits == null) ? 0 : this.splits.size();
    }

    public java.util.Iterator<java.nio.ByteBuffer> getSplitsIterator() {
      return (this.splits == null) ? null : this.splits.iterator();
    }

    public void addToSplits(java.nio.ByteBuffer elem) {
      if (this.splits == null) {
        this.splits = new java.util.HashSet<java.nio.ByteBuffer>();
      }
      this.splits.add(elem);
    }

    public java.util.Set<java.nio.ByteBuffer> getSplits() {
      return this.splits;
    }

    public addSplits_args setSplits(java.util.Set<java.nio.ByteBuffer> splits) {
      this.splits = splits;
      return this;
    }

    public void unsetSplits() {
      this.splits = null;
    }

    /** Returns true if field splits is set (has been assigned a value) and false otherwise */
    public boolean isSetSplits() {
      return this.splits != null;
    }

    public void setSplitsIsSet(boolean value) {
      if (!value) {
        this.splits = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case LOGIN:
        if (value == null) {
          unsetLogin();
        } else {
          if (value instanceof byte[]) {
            setLogin((byte[])value);
          } else {
            setLogin((java.nio.ByteBuffer)value);
          }
        }
        break;

      case TABLE_NAME:
        if (value == null) {
          unsetTableName();
        } else {
          setTableName((java.lang.String)value);
        }
        break;

      case SPLITS:
        if (value == null) {
          unsetSplits();
        } else {
          setSplits((java.util.Set<java.nio.ByteBuffer>)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case LOGIN:
        return getLogin();

      case TABLE_NAME:
        return getTableName();

      case SPLITS:
        return getSplits();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case LOGIN:
        return isSetLogin();
      case TABLE_NAME:
        return isSetTableName();
      case SPLITS:
        return isSetSplits();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof addSplits_args)
        return this.equals((addSplits_args)that);
      return false;
    }

    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();
      if (this_present_login || that_present_login) {
        if (!(this_present_login && that_present_login))
          return false;
        if (!this.login.equals(that.login))
          return false;
      }

      boolean this_present_tableName = true && this.isSetTableName();
      boolean that_present_tableName = true && that.isSetTableName();
      if (this_present_tableName || that_present_tableName) {
        if (!(this_present_tableName && that_present_tableName))
          return false;
        if (!this.tableName.equals(that.tableName))
          return false;
      }

      boolean this_present_splits = true && this.isSetSplits();
      boolean that_present_splits = true && that.isSetSplits();
      if (this_present_splits || that_present_splits) {
        if (!(this_present_splits && that_present_splits))
          return false;
        if (!this.splits.equals(that.splits))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
      if (isSetLogin())
        hashCode = hashCode * 8191 + login.hashCode();

      hashCode = hashCode * 8191 + ((isSetTableName()) ? 131071 : 524287);
      if (isSetTableName())
        hashCode = hashCode * 8191 + tableName.hashCode();

      hashCode = hashCode * 8191 + ((isSetSplits()) ? 131071 : 524287);
      if (isSetSplits())
        hashCode = hashCode * 8191 + splits.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(addSplits_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLogin()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetTableName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.tableName, other.tableName);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetSplits()).compareTo(other.isSetSplits());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSplits()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.splits, other.splits);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("addSplits_args(");
      boolean first = true;

      sb.append("login:");
      if (this.login == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.login, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("tableName:");
      if (this.tableName == null) {
        sb.append("null");
      } else {
        sb.append(this.tableName);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("splits:");
      if (this.splits == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.splits, sb);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class addSplits_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public addSplits_argsStandardScheme getScheme() {
        return new addSplits_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // LOGIN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.login = iprot.readBinary();
                struct.setLoginIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // TABLE_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.tableName = iprot.readString();
                struct.setTableNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // SPLITS
              if (schemeField.type == org.apache.thrift.protocol.TType.SET) {
                {
                  org.apache.thrift.protocol.TSet _set174 = iprot.readSetBegin();
                  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();
                    struct.splits.add(_elem175);
                  }
                  iprot.readSetEnd();
                }
                struct.setSplitsIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, addSplits_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.login != null) {
          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
          oprot.writeBinary(struct.login);
          oprot.writeFieldEnd();
        }
        if (struct.tableName != null) {
          oprot.writeFieldBegin(TABLE_NAME_FIELD_DESC);
          oprot.writeString(struct.tableName);
          oprot.writeFieldEnd();
        }
        if (struct.splits != null) {
          oprot.writeFieldBegin(SPLITS_FIELD_DESC);
          {
            oprot.writeSetBegin(new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRING, struct.splits.size()));
            for (java.nio.ByteBuffer _iter177 : struct.splits)
            {
              oprot.writeBinary(_iter177);
            }
            oprot.writeSetEnd();
          }
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    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 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 {
        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);
        }
        if (struct.isSetTableName()) {
          optionals.set(1);
        }
        if (struct.isSetSplits()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetLogin()) {
          oprot.writeBinary(struct.login);
        }
        if (struct.isSetTableName()) {
          oprot.writeString(struct.tableName);
        }
        if (struct.isSetSplits()) {
          {
            oprot.writeI32(struct.splits.size());
            for (java.nio.ByteBuffer _iter178 : struct.splits)
            {
              oprot.writeBinary(_iter178);
            }
          }
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, addSplits_args struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.tableName = iprot.readString();
          struct.setTableNameIsSet(true);
        }
        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 java.util.HashSet<java.nio.ByteBuffer>(2*_set179.size);
            java.nio.ByteBuffer _elem180;
            for (int _i181 = 0; _i181 < _set179.size; ++_i181)
            {
              _elem180 = iprot.readBinary();
              struct.splits.add(_elem180);
            }
          }
          struct.setSplitsIsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("addSplits_result");

    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField OUCH3_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch3", org.apache.thrift.protocol.TType.STRUCT, (short)3);

    private static final org.apache.thrift.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
    public TableNotFoundException ouch3; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      OUCH1((short)1, "ouch1"),
      OUCH2((short)2, "ouch2"),
      OUCH3((short)3, "ouch3");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // OUCH1
            return OUCH1;
          case 2: // OUCH2
            return OUCH2;
          case 3: // OUCH3
            return OUCH3;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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.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.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);
    }

    public addSplits_result() {
    }

    public addSplits_result(
      AccumuloException ouch1,
      AccumuloSecurityException ouch2,
      TableNotFoundException ouch3)
    {
      this();
      this.ouch1 = ouch1;
      this.ouch2 = ouch2;
      this.ouch3 = ouch3;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public addSplits_result(addSplits_result other) {
      if (other.isSetOuch1()) {
        this.ouch1 = new AccumuloException(other.ouch1);
      }
      if (other.isSetOuch2()) {
        this.ouch2 = new AccumuloSecurityException(other.ouch2);
      }
      if (other.isSetOuch3()) {
        this.ouch3 = new TableNotFoundException(other.ouch3);
      }
    }

    public addSplits_result deepCopy() {
      return new addSplits_result(this);
    }

    @Override
    public void clear() {
      this.ouch1 = null;
      this.ouch2 = null;
      this.ouch3 = null;
    }

    public AccumuloException getOuch1() {
      return this.ouch1;
    }

    public addSplits_result setOuch1(AccumuloException ouch1) {
      this.ouch1 = ouch1;
      return this;
    }

    public void unsetOuch1() {
      this.ouch1 = null;
    }

    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch1() {
      return this.ouch1 != null;
    }

    public void setOuch1IsSet(boolean value) {
      if (!value) {
        this.ouch1 = null;
      }
    }

    public AccumuloSecurityException getOuch2() {
      return this.ouch2;
    }

    public addSplits_result setOuch2(AccumuloSecurityException ouch2) {
      this.ouch2 = ouch2;
      return this;
    }

    public void unsetOuch2() {
      this.ouch2 = null;
    }

    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch2() {
      return this.ouch2 != null;
    }

    public void setOuch2IsSet(boolean value) {
      if (!value) {
        this.ouch2 = null;
      }
    }

    public TableNotFoundException getOuch3() {
      return this.ouch3;
    }

    public addSplits_result setOuch3(TableNotFoundException ouch3) {
      this.ouch3 = ouch3;
      return this;
    }

    public void unsetOuch3() {
      this.ouch3 = null;
    }

    /** Returns true if field ouch3 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch3() {
      return this.ouch3 != null;
    }

    public void setOuch3IsSet(boolean value) {
      if (!value) {
        this.ouch3 = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case OUCH1:
        if (value == null) {
          unsetOuch1();
        } else {
          setOuch1((AccumuloException)value);
        }
        break;

      case OUCH2:
        if (value == null) {
          unsetOuch2();
        } else {
          setOuch2((AccumuloSecurityException)value);
        }
        break;

      case OUCH3:
        if (value == null) {
          unsetOuch3();
        } else {
          setOuch3((TableNotFoundException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case OUCH1:
        return getOuch1();

      case OUCH2:
        return getOuch2();

      case OUCH3:
        return getOuch3();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case OUCH1:
        return isSetOuch1();
      case OUCH2:
        return isSetOuch2();
      case OUCH3:
        return isSetOuch3();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof addSplits_result)
        return this.equals((addSplits_result)that);
      return false;
    }

    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();
      if (this_present_ouch1 || that_present_ouch1) {
        if (!(this_present_ouch1 && that_present_ouch1))
          return false;
        if (!this.ouch1.equals(that.ouch1))
          return false;
      }

      boolean this_present_ouch2 = true && this.isSetOuch2();
      boolean that_present_ouch2 = true && that.isSetOuch2();
      if (this_present_ouch2 || that_present_ouch2) {
        if (!(this_present_ouch2 && that_present_ouch2))
          return false;
        if (!this.ouch2.equals(that.ouch2))
          return false;
      }

      boolean this_present_ouch3 = true && this.isSetOuch3();
      boolean that_present_ouch3 = true && that.isSetOuch3();
      if (this_present_ouch3 || that_present_ouch3) {
        if (!(this_present_ouch3 && that_present_ouch3))
          return false;
        if (!this.ouch3.equals(that.ouch3))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
      if (isSetOuch1())
        hashCode = hashCode * 8191 + ouch1.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
      if (isSetOuch2())
        hashCode = hashCode * 8191 + ouch2.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
      if (isSetOuch3())
        hashCode = hashCode * 8191 + ouch3.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(addSplits_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch1()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch2()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch3()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch3, other.ouch3);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("addSplits_result(");
      boolean first = true;

      sb.append("ouch1:");
      if (this.ouch1 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch1);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch2:");
      if (this.ouch2 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch2);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch3:");
      if (this.ouch3 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch3);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class addSplits_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public addSplits_resultStandardScheme getScheme() {
        return new addSplits_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // OUCH1
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch1 = new AccumuloException();
                struct.ouch1.read(iprot);
                struct.setOuch1IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OUCH2
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch2 = new AccumuloSecurityException();
                struct.ouch2.read(iprot);
                struct.setOuch2IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // OUCH3
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch3 = new TableNotFoundException();
                struct.ouch3.read(iprot);
                struct.setOuch3IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, addSplits_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.ouch1 != null) {
          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
          struct.ouch1.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch2 != null) {
          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
          struct.ouch2.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch3 != null) {
          oprot.writeFieldBegin(OUCH3_FIELD_DESC);
          struct.ouch3.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class addSplits_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public addSplits_resultTupleScheme getScheme() {
        return new addSplits_resultTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetOuch2()) {
          optionals.set(1);
        }
        if (struct.isSetOuch3()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetOuch1()) {
          struct.ouch1.write(oprot);
        }
        if (struct.isSetOuch2()) {
          struct.ouch2.write(oprot);
        }
        if (struct.isSetOuch3()) {
          struct.ouch3.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, addSplits_result struct) throws org.apache.thrift.TException {
        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);
          struct.setOuch1IsSet(true);
        }
        if (incoming.get(1)) {
          struct.ouch2 = new AccumuloSecurityException();
          struct.ouch2.read(iprot);
          struct.setOuch2IsSet(true);
        }
        if (incoming.get(2)) {
          struct.ouch3 = new TableNotFoundException();
          struct.ouch3.read(iprot);
          struct.setOuch3IsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("attachIterator_args");

    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField 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 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 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 java.nio.ByteBuffer login; // required
    public java.lang.String tableName; // required
    public IteratorSetting setting; // 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 {
      LOGIN((short)1, "login"),
      TABLE_NAME((short)2, "tableName"),
      SETTING((short)3, "setting"),
      SCOPES((short)4, "scopes");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // LOGIN
            return LOGIN;
          case 2: // TABLE_NAME
            return TABLE_NAME;
          case 3: // SETTING
            return SETTING;
          case 4: // SCOPES
            return SCOPES;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.SETTING, new org.apache.thrift.meta_data.FieldMetaData("setting", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, IteratorSetting.class)));
      tmpMap.put(_Fields.SCOPES, new org.apache.thrift.meta_data.FieldMetaData("scopes", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.SetMetaData(org.apache.thrift.protocol.TType.SET, 
              new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, IteratorScope.class))));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(attachIterator_args.class, metaDataMap);
    }

    public attachIterator_args() {
    }

    public attachIterator_args(
      java.nio.ByteBuffer login,
      java.lang.String tableName,
      IteratorSetting setting,
      java.util.Set<IteratorScope> scopes)
    {
      this();
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      this.tableName = tableName;
      this.setting = setting;
      this.scopes = scopes;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public attachIterator_args(attachIterator_args other) {
      if (other.isSetLogin()) {
        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
      }
      if (other.isSetTableName()) {
        this.tableName = other.tableName;
      }
      if (other.isSetSetting()) {
        this.setting = new IteratorSetting(other.setting);
      }
      if (other.isSetScopes()) {
        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);
        }
        this.scopes = __this__scopes;
      }
    }

    public attachIterator_args deepCopy() {
      return new attachIterator_args(this);
    }

    @Override
    public void clear() {
      this.login = null;
      this.tableName = null;
      this.setting = null;
      this.scopes = null;
    }

    public byte[] getLogin() {
      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
      return login == null ? null : login.array();
    }

    public java.nio.ByteBuffer bufferForLogin() {
      return org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    public attachIterator_args setLogin(byte[] login) {
      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
      return this;
    }

    public attachIterator_args setLogin(java.nio.ByteBuffer login) {
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      return this;
    }

    public void unsetLogin() {
      this.login = null;
    }

    /** Returns true if field login is set (has been assigned a value) and false otherwise */
    public boolean isSetLogin() {
      return this.login != null;
    }

    public void setLoginIsSet(boolean value) {
      if (!value) {
        this.login = null;
      }
    }

    public java.lang.String getTableName() {
      return this.tableName;
    }

    public attachIterator_args setTableName(java.lang.String tableName) {
      this.tableName = tableName;
      return this;
    }

    public void unsetTableName() {
      this.tableName = null;
    }

    /** Returns true if field tableName is set (has been assigned a value) and false otherwise */
    public boolean isSetTableName() {
      return this.tableName != null;
    }

    public void setTableNameIsSet(boolean value) {
      if (!value) {
        this.tableName = null;
      }
    }

    public IteratorSetting getSetting() {
      return this.setting;
    }

    public attachIterator_args setSetting(IteratorSetting setting) {
      this.setting = setting;
      return this;
    }

    public void unsetSetting() {
      this.setting = null;
    }

    /** Returns true if field setting is set (has been assigned a value) and false otherwise */
    public boolean isSetSetting() {
      return this.setting != null;
    }

    public void setSettingIsSet(boolean value) {
      if (!value) {
        this.setting = null;
      }
    }

    public int getScopesSize() {
      return (this.scopes == null) ? 0 : this.scopes.size();
    }

    public java.util.Iterator<IteratorScope> getScopesIterator() {
      return (this.scopes == null) ? null : this.scopes.iterator();
    }

    public void addToScopes(IteratorScope elem) {
      if (this.scopes == null) {
        this.scopes = new java.util.HashSet<IteratorScope>();
      }
      this.scopes.add(elem);
    }

    public java.util.Set<IteratorScope> getScopes() {
      return this.scopes;
    }

    public attachIterator_args setScopes(java.util.Set<IteratorScope> scopes) {
      this.scopes = scopes;
      return this;
    }

    public void unsetScopes() {
      this.scopes = null;
    }

    /** Returns true if field scopes is set (has been assigned a value) and false otherwise */
    public boolean isSetScopes() {
      return this.scopes != null;
    }

    public void setScopesIsSet(boolean value) {
      if (!value) {
        this.scopes = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case LOGIN:
        if (value == null) {
          unsetLogin();
        } else {
          if (value instanceof byte[]) {
            setLogin((byte[])value);
          } else {
            setLogin((java.nio.ByteBuffer)value);
          }
        }
        break;

      case TABLE_NAME:
        if (value == null) {
          unsetTableName();
        } else {
          setTableName((java.lang.String)value);
        }
        break;

      case SETTING:
        if (value == null) {
          unsetSetting();
        } else {
          setSetting((IteratorSetting)value);
        }
        break;

      case SCOPES:
        if (value == null) {
          unsetScopes();
        } else {
          setScopes((java.util.Set<IteratorScope>)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case LOGIN:
        return getLogin();

      case TABLE_NAME:
        return getTableName();

      case SETTING:
        return getSetting();

      case SCOPES:
        return getScopes();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case LOGIN:
        return isSetLogin();
      case TABLE_NAME:
        return isSetTableName();
      case SETTING:
        return isSetSetting();
      case SCOPES:
        return isSetScopes();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof attachIterator_args)
        return this.equals((attachIterator_args)that);
      return false;
    }

    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();
      if (this_present_login || that_present_login) {
        if (!(this_present_login && that_present_login))
          return false;
        if (!this.login.equals(that.login))
          return false;
      }

      boolean this_present_tableName = true && this.isSetTableName();
      boolean that_present_tableName = true && that.isSetTableName();
      if (this_present_tableName || that_present_tableName) {
        if (!(this_present_tableName && that_present_tableName))
          return false;
        if (!this.tableName.equals(that.tableName))
          return false;
      }

      boolean this_present_setting = true && this.isSetSetting();
      boolean that_present_setting = true && that.isSetSetting();
      if (this_present_setting || that_present_setting) {
        if (!(this_present_setting && that_present_setting))
          return false;
        if (!this.setting.equals(that.setting))
          return false;
      }

      boolean this_present_scopes = true && this.isSetScopes();
      boolean that_present_scopes = true && that.isSetScopes();
      if (this_present_scopes || that_present_scopes) {
        if (!(this_present_scopes && that_present_scopes))
          return false;
        if (!this.scopes.equals(that.scopes))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
      if (isSetLogin())
        hashCode = hashCode * 8191 + login.hashCode();

      hashCode = hashCode * 8191 + ((isSetTableName()) ? 131071 : 524287);
      if (isSetTableName())
        hashCode = hashCode * 8191 + tableName.hashCode();

      hashCode = hashCode * 8191 + ((isSetSetting()) ? 131071 : 524287);
      if (isSetSetting())
        hashCode = hashCode * 8191 + setting.hashCode();

      hashCode = hashCode * 8191 + ((isSetScopes()) ? 131071 : 524287);
      if (isSetScopes())
        hashCode = hashCode * 8191 + scopes.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(attachIterator_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLogin()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetTableName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.tableName, other.tableName);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetSetting()).compareTo(other.isSetSetting());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSetting()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.setting, other.setting);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetScopes()).compareTo(other.isSetScopes());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetScopes()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.scopes, other.scopes);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("attachIterator_args(");
      boolean first = true;

      sb.append("login:");
      if (this.login == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.login, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("tableName:");
      if (this.tableName == null) {
        sb.append("null");
      } else {
        sb.append(this.tableName);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("setting:");
      if (this.setting == null) {
        sb.append("null");
      } else {
        sb.append(this.setting);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("scopes:");
      if (this.scopes == null) {
        sb.append("null");
      } else {
        sb.append(this.scopes);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
      if (setting != null) {
        setting.validate();
      }
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class attachIterator_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public attachIterator_argsStandardScheme getScheme() {
        return new attachIterator_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // LOGIN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.login = iprot.readBinary();
                struct.setLoginIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // TABLE_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.tableName = iprot.readString();
                struct.setTableNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // SETTING
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.setting = new IteratorSetting();
                struct.setting.read(iprot);
                struct.setSettingIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // SCOPES
              if (schemeField.type == org.apache.thrift.protocol.TType.SET) {
                {
                  org.apache.thrift.protocol.TSet _set182 = iprot.readSetBegin();
                  struct.scopes = new java.util.HashSet<IteratorScope>(2*_set182.size);
                  IteratorScope _elem183;
                  for (int _i184 = 0; _i184 < _set182.size; ++_i184)
                  {
                    _elem183 = org.apache.accumulo.proxy.thrift.IteratorScope.findByValue(iprot.readI32());
                    struct.scopes.add(_elem183);
                  }
                  iprot.readSetEnd();
                }
                struct.setScopesIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, attachIterator_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.login != null) {
          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
          oprot.writeBinary(struct.login);
          oprot.writeFieldEnd();
        }
        if (struct.tableName != null) {
          oprot.writeFieldBegin(TABLE_NAME_FIELD_DESC);
          oprot.writeString(struct.tableName);
          oprot.writeFieldEnd();
        }
        if (struct.setting != null) {
          oprot.writeFieldBegin(SETTING_FIELD_DESC);
          struct.setting.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.scopes != null) {
          oprot.writeFieldBegin(SCOPES_FIELD_DESC);
          {
            oprot.writeSetBegin(new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.I32, struct.scopes.size()));
            for (IteratorScope _iter185 : struct.scopes)
            {
              oprot.writeI32(_iter185.getValue());
            }
            oprot.writeSetEnd();
          }
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    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 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 {
        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);
        }
        if (struct.isSetTableName()) {
          optionals.set(1);
        }
        if (struct.isSetSetting()) {
          optionals.set(2);
        }
        if (struct.isSetScopes()) {
          optionals.set(3);
        }
        oprot.writeBitSet(optionals, 4);
        if (struct.isSetLogin()) {
          oprot.writeBinary(struct.login);
        }
        if (struct.isSetTableName()) {
          oprot.writeString(struct.tableName);
        }
        if (struct.isSetSetting()) {
          struct.setting.write(oprot);
        }
        if (struct.isSetScopes()) {
          {
            oprot.writeI32(struct.scopes.size());
            for (IteratorScope _iter186 : struct.scopes)
            {
              oprot.writeI32(_iter186.getValue());
            }
          }
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, attachIterator_args struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.tableName = iprot.readString();
          struct.setTableNameIsSet(true);
        }
        if (incoming.get(2)) {
          struct.setting = new IteratorSetting();
          struct.setting.read(iprot);
          struct.setSettingIsSet(true);
        }
        if (incoming.get(3)) {
          {
            org.apache.thrift.protocol.TSet _set187 = new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.I32, iprot.readI32());
            struct.scopes = new java.util.HashSet<IteratorScope>(2*_set187.size);
            IteratorScope _elem188;
            for (int _i189 = 0; _i189 < _set187.size; ++_i189)
            {
              _elem188 = org.apache.accumulo.proxy.thrift.IteratorScope.findByValue(iprot.readI32());
              struct.scopes.add(_elem188);
            }
          }
          struct.setScopesIsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("attachIterator_result");

    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField OUCH3_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch3", org.apache.thrift.protocol.TType.STRUCT, (short)3);

    private static final org.apache.thrift.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
    public TableNotFoundException ouch3; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      OUCH1((short)1, "ouch1"),
      OUCH2((short)2, "ouch2"),
      OUCH3((short)3, "ouch3");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // OUCH1
            return OUCH1;
          case 2: // OUCH2
            return OUCH2;
          case 3: // OUCH3
            return OUCH3;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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.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.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);
    }

    public attachIterator_result() {
    }

    public attachIterator_result(
      AccumuloSecurityException ouch1,
      AccumuloException ouch2,
      TableNotFoundException ouch3)
    {
      this();
      this.ouch1 = ouch1;
      this.ouch2 = ouch2;
      this.ouch3 = ouch3;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public attachIterator_result(attachIterator_result other) {
      if (other.isSetOuch1()) {
        this.ouch1 = new AccumuloSecurityException(other.ouch1);
      }
      if (other.isSetOuch2()) {
        this.ouch2 = new AccumuloException(other.ouch2);
      }
      if (other.isSetOuch3()) {
        this.ouch3 = new TableNotFoundException(other.ouch3);
      }
    }

    public attachIterator_result deepCopy() {
      return new attachIterator_result(this);
    }

    @Override
    public void clear() {
      this.ouch1 = null;
      this.ouch2 = null;
      this.ouch3 = null;
    }

    public AccumuloSecurityException getOuch1() {
      return this.ouch1;
    }

    public attachIterator_result setOuch1(AccumuloSecurityException ouch1) {
      this.ouch1 = ouch1;
      return this;
    }

    public void unsetOuch1() {
      this.ouch1 = null;
    }

    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch1() {
      return this.ouch1 != null;
    }

    public void setOuch1IsSet(boolean value) {
      if (!value) {
        this.ouch1 = null;
      }
    }

    public AccumuloException getOuch2() {
      return this.ouch2;
    }

    public attachIterator_result setOuch2(AccumuloException ouch2) {
      this.ouch2 = ouch2;
      return this;
    }

    public void unsetOuch2() {
      this.ouch2 = null;
    }

    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch2() {
      return this.ouch2 != null;
    }

    public void setOuch2IsSet(boolean value) {
      if (!value) {
        this.ouch2 = null;
      }
    }

    public TableNotFoundException getOuch3() {
      return this.ouch3;
    }

    public attachIterator_result setOuch3(TableNotFoundException ouch3) {
      this.ouch3 = ouch3;
      return this;
    }

    public void unsetOuch3() {
      this.ouch3 = null;
    }

    /** Returns true if field ouch3 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch3() {
      return this.ouch3 != null;
    }

    public void setOuch3IsSet(boolean value) {
      if (!value) {
        this.ouch3 = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case OUCH1:
        if (value == null) {
          unsetOuch1();
        } else {
          setOuch1((AccumuloSecurityException)value);
        }
        break;

      case OUCH2:
        if (value == null) {
          unsetOuch2();
        } else {
          setOuch2((AccumuloException)value);
        }
        break;

      case OUCH3:
        if (value == null) {
          unsetOuch3();
        } else {
          setOuch3((TableNotFoundException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case OUCH1:
        return getOuch1();

      case OUCH2:
        return getOuch2();

      case OUCH3:
        return getOuch3();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case OUCH1:
        return isSetOuch1();
      case OUCH2:
        return isSetOuch2();
      case OUCH3:
        return isSetOuch3();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof attachIterator_result)
        return this.equals((attachIterator_result)that);
      return false;
    }

    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();
      if (this_present_ouch1 || that_present_ouch1) {
        if (!(this_present_ouch1 && that_present_ouch1))
          return false;
        if (!this.ouch1.equals(that.ouch1))
          return false;
      }

      boolean this_present_ouch2 = true && this.isSetOuch2();
      boolean that_present_ouch2 = true && that.isSetOuch2();
      if (this_present_ouch2 || that_present_ouch2) {
        if (!(this_present_ouch2 && that_present_ouch2))
          return false;
        if (!this.ouch2.equals(that.ouch2))
          return false;
      }

      boolean this_present_ouch3 = true && this.isSetOuch3();
      boolean that_present_ouch3 = true && that.isSetOuch3();
      if (this_present_ouch3 || that_present_ouch3) {
        if (!(this_present_ouch3 && that_present_ouch3))
          return false;
        if (!this.ouch3.equals(that.ouch3))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
      if (isSetOuch1())
        hashCode = hashCode * 8191 + ouch1.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
      if (isSetOuch2())
        hashCode = hashCode * 8191 + ouch2.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
      if (isSetOuch3())
        hashCode = hashCode * 8191 + ouch3.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(attachIterator_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch1()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch2()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch3()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch3, other.ouch3);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("attachIterator_result(");
      boolean first = true;

      sb.append("ouch1:");
      if (this.ouch1 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch1);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch2:");
      if (this.ouch2 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch2);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch3:");
      if (this.ouch3 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch3);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class attachIterator_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public attachIterator_resultStandardScheme getScheme() {
        return new attachIterator_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // OUCH1
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch1 = new AccumuloSecurityException();
                struct.ouch1.read(iprot);
                struct.setOuch1IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OUCH2
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch2 = new AccumuloException();
                struct.ouch2.read(iprot);
                struct.setOuch2IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // OUCH3
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch3 = new TableNotFoundException();
                struct.ouch3.read(iprot);
                struct.setOuch3IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, attachIterator_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.ouch1 != null) {
          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
          struct.ouch1.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch2 != null) {
          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
          struct.ouch2.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch3 != null) {
          oprot.writeFieldBegin(OUCH3_FIELD_DESC);
          struct.ouch3.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class attachIterator_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public attachIterator_resultTupleScheme getScheme() {
        return new attachIterator_resultTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetOuch2()) {
          optionals.set(1);
        }
        if (struct.isSetOuch3()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetOuch1()) {
          struct.ouch1.write(oprot);
        }
        if (struct.isSetOuch2()) {
          struct.ouch2.write(oprot);
        }
        if (struct.isSetOuch3()) {
          struct.ouch3.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, attachIterator_result struct) throws org.apache.thrift.TException {
        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);
          struct.setOuch1IsSet(true);
        }
        if (incoming.get(1)) {
          struct.ouch2 = new AccumuloException();
          struct.ouch2.read(iprot);
          struct.setOuch2IsSet(true);
        }
        if (incoming.get(2)) {
          struct.ouch3 = new TableNotFoundException();
          struct.ouch3.read(iprot);
          struct.setOuch3IsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("checkIteratorConflicts_args");

    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField 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 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 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 java.nio.ByteBuffer login; // required
    public java.lang.String tableName; // required
    public IteratorSetting setting; // 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 {
      LOGIN((short)1, "login"),
      TABLE_NAME((short)2, "tableName"),
      SETTING((short)3, "setting"),
      SCOPES((short)4, "scopes");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // LOGIN
            return LOGIN;
          case 2: // TABLE_NAME
            return TABLE_NAME;
          case 3: // SETTING
            return SETTING;
          case 4: // SCOPES
            return SCOPES;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.SETTING, new org.apache.thrift.meta_data.FieldMetaData("setting", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, IteratorSetting.class)));
      tmpMap.put(_Fields.SCOPES, new org.apache.thrift.meta_data.FieldMetaData("scopes", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.SetMetaData(org.apache.thrift.protocol.TType.SET, 
              new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, IteratorScope.class))));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(checkIteratorConflicts_args.class, metaDataMap);
    }

    public checkIteratorConflicts_args() {
    }

    public checkIteratorConflicts_args(
      java.nio.ByteBuffer login,
      java.lang.String tableName,
      IteratorSetting setting,
      java.util.Set<IteratorScope> scopes)
    {
      this();
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      this.tableName = tableName;
      this.setting = setting;
      this.scopes = scopes;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public checkIteratorConflicts_args(checkIteratorConflicts_args other) {
      if (other.isSetLogin()) {
        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
      }
      if (other.isSetTableName()) {
        this.tableName = other.tableName;
      }
      if (other.isSetSetting()) {
        this.setting = new IteratorSetting(other.setting);
      }
      if (other.isSetScopes()) {
        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);
        }
        this.scopes = __this__scopes;
      }
    }

    public checkIteratorConflicts_args deepCopy() {
      return new checkIteratorConflicts_args(this);
    }

    @Override
    public void clear() {
      this.login = null;
      this.tableName = null;
      this.setting = null;
      this.scopes = null;
    }

    public byte[] getLogin() {
      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
      return login == null ? null : login.array();
    }

    public java.nio.ByteBuffer bufferForLogin() {
      return org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    public checkIteratorConflicts_args setLogin(byte[] login) {
      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
      return this;
    }

    public checkIteratorConflicts_args setLogin(java.nio.ByteBuffer login) {
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      return this;
    }

    public void unsetLogin() {
      this.login = null;
    }

    /** Returns true if field login is set (has been assigned a value) and false otherwise */
    public boolean isSetLogin() {
      return this.login != null;
    }

    public void setLoginIsSet(boolean value) {
      if (!value) {
        this.login = null;
      }
    }

    public java.lang.String getTableName() {
      return this.tableName;
    }

    public checkIteratorConflicts_args setTableName(java.lang.String tableName) {
      this.tableName = tableName;
      return this;
    }

    public void unsetTableName() {
      this.tableName = null;
    }

    /** Returns true if field tableName is set (has been assigned a value) and false otherwise */
    public boolean isSetTableName() {
      return this.tableName != null;
    }

    public void setTableNameIsSet(boolean value) {
      if (!value) {
        this.tableName = null;
      }
    }

    public IteratorSetting getSetting() {
      return this.setting;
    }

    public checkIteratorConflicts_args setSetting(IteratorSetting setting) {
      this.setting = setting;
      return this;
    }

    public void unsetSetting() {
      this.setting = null;
    }

    /** Returns true if field setting is set (has been assigned a value) and false otherwise */
    public boolean isSetSetting() {
      return this.setting != null;
    }

    public void setSettingIsSet(boolean value) {
      if (!value) {
        this.setting = null;
      }
    }

    public int getScopesSize() {
      return (this.scopes == null) ? 0 : this.scopes.size();
    }

    public java.util.Iterator<IteratorScope> getScopesIterator() {
      return (this.scopes == null) ? null : this.scopes.iterator();
    }

    public void addToScopes(IteratorScope elem) {
      if (this.scopes == null) {
        this.scopes = new java.util.HashSet<IteratorScope>();
      }
      this.scopes.add(elem);
    }

    public java.util.Set<IteratorScope> getScopes() {
      return this.scopes;
    }

    public checkIteratorConflicts_args setScopes(java.util.Set<IteratorScope> scopes) {
      this.scopes = scopes;
      return this;
    }

    public void unsetScopes() {
      this.scopes = null;
    }

    /** Returns true if field scopes is set (has been assigned a value) and false otherwise */
    public boolean isSetScopes() {
      return this.scopes != null;
    }

    public void setScopesIsSet(boolean value) {
      if (!value) {
        this.scopes = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case LOGIN:
        if (value == null) {
          unsetLogin();
        } else {
          if (value instanceof byte[]) {
            setLogin((byte[])value);
          } else {
            setLogin((java.nio.ByteBuffer)value);
          }
        }
        break;

      case TABLE_NAME:
        if (value == null) {
          unsetTableName();
        } else {
          setTableName((java.lang.String)value);
        }
        break;

      case SETTING:
        if (value == null) {
          unsetSetting();
        } else {
          setSetting((IteratorSetting)value);
        }
        break;

      case SCOPES:
        if (value == null) {
          unsetScopes();
        } else {
          setScopes((java.util.Set<IteratorScope>)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case LOGIN:
        return getLogin();

      case TABLE_NAME:
        return getTableName();

      case SETTING:
        return getSetting();

      case SCOPES:
        return getScopes();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case LOGIN:
        return isSetLogin();
      case TABLE_NAME:
        return isSetTableName();
      case SETTING:
        return isSetSetting();
      case SCOPES:
        return isSetScopes();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof checkIteratorConflicts_args)
        return this.equals((checkIteratorConflicts_args)that);
      return false;
    }

    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();
      if (this_present_login || that_present_login) {
        if (!(this_present_login && that_present_login))
          return false;
        if (!this.login.equals(that.login))
          return false;
      }

      boolean this_present_tableName = true && this.isSetTableName();
      boolean that_present_tableName = true && that.isSetTableName();
      if (this_present_tableName || that_present_tableName) {
        if (!(this_present_tableName && that_present_tableName))
          return false;
        if (!this.tableName.equals(that.tableName))
          return false;
      }

      boolean this_present_setting = true && this.isSetSetting();
      boolean that_present_setting = true && that.isSetSetting();
      if (this_present_setting || that_present_setting) {
        if (!(this_present_setting && that_present_setting))
          return false;
        if (!this.setting.equals(that.setting))
          return false;
      }

      boolean this_present_scopes = true && this.isSetScopes();
      boolean that_present_scopes = true && that.isSetScopes();
      if (this_present_scopes || that_present_scopes) {
        if (!(this_present_scopes && that_present_scopes))
          return false;
        if (!this.scopes.equals(that.scopes))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
      if (isSetLogin())
        hashCode = hashCode * 8191 + login.hashCode();

      hashCode = hashCode * 8191 + ((isSetTableName()) ? 131071 : 524287);
      if (isSetTableName())
        hashCode = hashCode * 8191 + tableName.hashCode();

      hashCode = hashCode * 8191 + ((isSetSetting()) ? 131071 : 524287);
      if (isSetSetting())
        hashCode = hashCode * 8191 + setting.hashCode();

      hashCode = hashCode * 8191 + ((isSetScopes()) ? 131071 : 524287);
      if (isSetScopes())
        hashCode = hashCode * 8191 + scopes.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(checkIteratorConflicts_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLogin()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetTableName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.tableName, other.tableName);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetSetting()).compareTo(other.isSetSetting());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSetting()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.setting, other.setting);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetScopes()).compareTo(other.isSetScopes());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetScopes()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.scopes, other.scopes);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("checkIteratorConflicts_args(");
      boolean first = true;

      sb.append("login:");
      if (this.login == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.login, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("tableName:");
      if (this.tableName == null) {
        sb.append("null");
      } else {
        sb.append(this.tableName);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("setting:");
      if (this.setting == null) {
        sb.append("null");
      } else {
        sb.append(this.setting);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("scopes:");
      if (this.scopes == null) {
        sb.append("null");
      } else {
        sb.append(this.scopes);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
      if (setting != null) {
        setting.validate();
      }
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class checkIteratorConflicts_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public checkIteratorConflicts_argsStandardScheme getScheme() {
        return new checkIteratorConflicts_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // LOGIN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.login = iprot.readBinary();
                struct.setLoginIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // TABLE_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.tableName = iprot.readString();
                struct.setTableNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // SETTING
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.setting = new IteratorSetting();
                struct.setting.read(iprot);
                struct.setSettingIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // SCOPES
              if (schemeField.type == org.apache.thrift.protocol.TType.SET) {
                {
                  org.apache.thrift.protocol.TSet _set190 = iprot.readSetBegin();
                  struct.scopes = new java.util.HashSet<IteratorScope>(2*_set190.size);
                  IteratorScope _elem191;
                  for (int _i192 = 0; _i192 < _set190.size; ++_i192)
                  {
                    _elem191 = org.apache.accumulo.proxy.thrift.IteratorScope.findByValue(iprot.readI32());
                    struct.scopes.add(_elem191);
                  }
                  iprot.readSetEnd();
                }
                struct.setScopesIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, checkIteratorConflicts_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.login != null) {
          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
          oprot.writeBinary(struct.login);
          oprot.writeFieldEnd();
        }
        if (struct.tableName != null) {
          oprot.writeFieldBegin(TABLE_NAME_FIELD_DESC);
          oprot.writeString(struct.tableName);
          oprot.writeFieldEnd();
        }
        if (struct.setting != null) {
          oprot.writeFieldBegin(SETTING_FIELD_DESC);
          struct.setting.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.scopes != null) {
          oprot.writeFieldBegin(SCOPES_FIELD_DESC);
          {
            oprot.writeSetBegin(new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.I32, struct.scopes.size()));
            for (IteratorScope _iter193 : struct.scopes)
            {
              oprot.writeI32(_iter193.getValue());
            }
            oprot.writeSetEnd();
          }
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    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 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 {
        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);
        }
        if (struct.isSetTableName()) {
          optionals.set(1);
        }
        if (struct.isSetSetting()) {
          optionals.set(2);
        }
        if (struct.isSetScopes()) {
          optionals.set(3);
        }
        oprot.writeBitSet(optionals, 4);
        if (struct.isSetLogin()) {
          oprot.writeBinary(struct.login);
        }
        if (struct.isSetTableName()) {
          oprot.writeString(struct.tableName);
        }
        if (struct.isSetSetting()) {
          struct.setting.write(oprot);
        }
        if (struct.isSetScopes()) {
          {
            oprot.writeI32(struct.scopes.size());
            for (IteratorScope _iter194 : struct.scopes)
            {
              oprot.writeI32(_iter194.getValue());
            }
          }
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, checkIteratorConflicts_args struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.tableName = iprot.readString();
          struct.setTableNameIsSet(true);
        }
        if (incoming.get(2)) {
          struct.setting = new IteratorSetting();
          struct.setting.read(iprot);
          struct.setSettingIsSet(true);
        }
        if (incoming.get(3)) {
          {
            org.apache.thrift.protocol.TSet _set195 = new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.I32, iprot.readI32());
            struct.scopes = new java.util.HashSet<IteratorScope>(2*_set195.size);
            IteratorScope _elem196;
            for (int _i197 = 0; _i197 < _set195.size; ++_i197)
            {
              _elem196 = org.apache.accumulo.proxy.thrift.IteratorScope.findByValue(iprot.readI32());
              struct.scopes.add(_elem196);
            }
          }
          struct.setScopesIsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("checkIteratorConflicts_result");

    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField OUCH3_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch3", org.apache.thrift.protocol.TType.STRUCT, (short)3);

    private static final org.apache.thrift.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
    public TableNotFoundException ouch3; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      OUCH1((short)1, "ouch1"),
      OUCH2((short)2, "ouch2"),
      OUCH3((short)3, "ouch3");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // OUCH1
            return OUCH1;
          case 2: // OUCH2
            return OUCH2;
          case 3: // OUCH3
            return OUCH3;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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.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.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);
    }

    public checkIteratorConflicts_result() {
    }

    public checkIteratorConflicts_result(
      AccumuloSecurityException ouch1,
      AccumuloException ouch2,
      TableNotFoundException ouch3)
    {
      this();
      this.ouch1 = ouch1;
      this.ouch2 = ouch2;
      this.ouch3 = ouch3;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public checkIteratorConflicts_result(checkIteratorConflicts_result other) {
      if (other.isSetOuch1()) {
        this.ouch1 = new AccumuloSecurityException(other.ouch1);
      }
      if (other.isSetOuch2()) {
        this.ouch2 = new AccumuloException(other.ouch2);
      }
      if (other.isSetOuch3()) {
        this.ouch3 = new TableNotFoundException(other.ouch3);
      }
    }

    public checkIteratorConflicts_result deepCopy() {
      return new checkIteratorConflicts_result(this);
    }

    @Override
    public void clear() {
      this.ouch1 = null;
      this.ouch2 = null;
      this.ouch3 = null;
    }

    public AccumuloSecurityException getOuch1() {
      return this.ouch1;
    }

    public checkIteratorConflicts_result setOuch1(AccumuloSecurityException ouch1) {
      this.ouch1 = ouch1;
      return this;
    }

    public void unsetOuch1() {
      this.ouch1 = null;
    }

    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch1() {
      return this.ouch1 != null;
    }

    public void setOuch1IsSet(boolean value) {
      if (!value) {
        this.ouch1 = null;
      }
    }

    public AccumuloException getOuch2() {
      return this.ouch2;
    }

    public checkIteratorConflicts_result setOuch2(AccumuloException ouch2) {
      this.ouch2 = ouch2;
      return this;
    }

    public void unsetOuch2() {
      this.ouch2 = null;
    }

    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch2() {
      return this.ouch2 != null;
    }

    public void setOuch2IsSet(boolean value) {
      if (!value) {
        this.ouch2 = null;
      }
    }

    public TableNotFoundException getOuch3() {
      return this.ouch3;
    }

    public checkIteratorConflicts_result setOuch3(TableNotFoundException ouch3) {
      this.ouch3 = ouch3;
      return this;
    }

    public void unsetOuch3() {
      this.ouch3 = null;
    }

    /** Returns true if field ouch3 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch3() {
      return this.ouch3 != null;
    }

    public void setOuch3IsSet(boolean value) {
      if (!value) {
        this.ouch3 = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case OUCH1:
        if (value == null) {
          unsetOuch1();
        } else {
          setOuch1((AccumuloSecurityException)value);
        }
        break;

      case OUCH2:
        if (value == null) {
          unsetOuch2();
        } else {
          setOuch2((AccumuloException)value);
        }
        break;

      case OUCH3:
        if (value == null) {
          unsetOuch3();
        } else {
          setOuch3((TableNotFoundException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case OUCH1:
        return getOuch1();

      case OUCH2:
        return getOuch2();

      case OUCH3:
        return getOuch3();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case OUCH1:
        return isSetOuch1();
      case OUCH2:
        return isSetOuch2();
      case OUCH3:
        return isSetOuch3();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof checkIteratorConflicts_result)
        return this.equals((checkIteratorConflicts_result)that);
      return false;
    }

    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();
      if (this_present_ouch1 || that_present_ouch1) {
        if (!(this_present_ouch1 && that_present_ouch1))
          return false;
        if (!this.ouch1.equals(that.ouch1))
          return false;
      }

      boolean this_present_ouch2 = true && this.isSetOuch2();
      boolean that_present_ouch2 = true && that.isSetOuch2();
      if (this_present_ouch2 || that_present_ouch2) {
        if (!(this_present_ouch2 && that_present_ouch2))
          return false;
        if (!this.ouch2.equals(that.ouch2))
          return false;
      }

      boolean this_present_ouch3 = true && this.isSetOuch3();
      boolean that_present_ouch3 = true && that.isSetOuch3();
      if (this_present_ouch3 || that_present_ouch3) {
        if (!(this_present_ouch3 && that_present_ouch3))
          return false;
        if (!this.ouch3.equals(that.ouch3))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
      if (isSetOuch1())
        hashCode = hashCode * 8191 + ouch1.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
      if (isSetOuch2())
        hashCode = hashCode * 8191 + ouch2.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
      if (isSetOuch3())
        hashCode = hashCode * 8191 + ouch3.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(checkIteratorConflicts_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch1()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch2()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch3()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch3, other.ouch3);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("checkIteratorConflicts_result(");
      boolean first = true;

      sb.append("ouch1:");
      if (this.ouch1 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch1);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch2:");
      if (this.ouch2 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch2);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch3:");
      if (this.ouch3 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch3);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class checkIteratorConflicts_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public checkIteratorConflicts_resultStandardScheme getScheme() {
        return new checkIteratorConflicts_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // OUCH1
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch1 = new AccumuloSecurityException();
                struct.ouch1.read(iprot);
                struct.setOuch1IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OUCH2
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch2 = new AccumuloException();
                struct.ouch2.read(iprot);
                struct.setOuch2IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // OUCH3
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch3 = new TableNotFoundException();
                struct.ouch3.read(iprot);
                struct.setOuch3IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, checkIteratorConflicts_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.ouch1 != null) {
          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
          struct.ouch1.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch2 != null) {
          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
          struct.ouch2.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch3 != null) {
          oprot.writeFieldBegin(OUCH3_FIELD_DESC);
          struct.ouch3.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class checkIteratorConflicts_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public checkIteratorConflicts_resultTupleScheme getScheme() {
        return new checkIteratorConflicts_resultTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetOuch2()) {
          optionals.set(1);
        }
        if (struct.isSetOuch3()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetOuch1()) {
          struct.ouch1.write(oprot);
        }
        if (struct.isSetOuch2()) {
          struct.ouch2.write(oprot);
        }
        if (struct.isSetOuch3()) {
          struct.ouch3.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, checkIteratorConflicts_result struct) throws org.apache.thrift.TException {
        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);
          struct.setOuch1IsSet(true);
        }
        if (incoming.get(1)) {
          struct.ouch2 = new AccumuloException();
          struct.ouch2.read(iprot);
          struct.setOuch2IsSet(true);
        }
        if (incoming.get(2)) {
          struct.ouch3 = new TableNotFoundException();
          struct.ouch3.read(iprot);
          struct.setOuch3IsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("clearLocatorCache_args");

    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField 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.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new clearLocatorCache_argsStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new clearLocatorCache_argsTupleSchemeFactory();

    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 java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // LOGIN
            return LOGIN;
          case 2: // TABLE_NAME
            return TABLE_NAME;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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 = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(clearLocatorCache_args.class, metaDataMap);
    }

    public clearLocatorCache_args() {
    }

    public clearLocatorCache_args(
      java.nio.ByteBuffer login,
      java.lang.String tableName)
    {
      this();
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      this.tableName = tableName;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public clearLocatorCache_args(clearLocatorCache_args other) {
      if (other.isSetLogin()) {
        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
      }
      if (other.isSetTableName()) {
        this.tableName = other.tableName;
      }
    }

    public clearLocatorCache_args deepCopy() {
      return new clearLocatorCache_args(this);
    }

    @Override
    public void clear() {
      this.login = null;
      this.tableName = null;
    }

    public byte[] getLogin() {
      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
      return login == null ? null : login.array();
    }

    public java.nio.ByteBuffer bufferForLogin() {
      return org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    public clearLocatorCache_args setLogin(byte[] login) {
      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
      return this;
    }

    public clearLocatorCache_args setLogin(java.nio.ByteBuffer login) {
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      return this;
    }

    public void unsetLogin() {
      this.login = null;
    }

    /** Returns true if field login is set (has been assigned a value) and false otherwise */
    public boolean isSetLogin() {
      return this.login != null;
    }

    public void setLoginIsSet(boolean value) {
      if (!value) {
        this.login = null;
      }
    }

    public java.lang.String getTableName() {
      return this.tableName;
    }

    public clearLocatorCache_args setTableName(java.lang.String tableName) {
      this.tableName = tableName;
      return this;
    }

    public void unsetTableName() {
      this.tableName = null;
    }

    /** Returns true if field tableName is set (has been assigned a value) and false otherwise */
    public boolean isSetTableName() {
      return this.tableName != null;
    }

    public void setTableNameIsSet(boolean value) {
      if (!value) {
        this.tableName = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case LOGIN:
        if (value == null) {
          unsetLogin();
        } else {
          if (value instanceof byte[]) {
            setLogin((byte[])value);
          } else {
            setLogin((java.nio.ByteBuffer)value);
          }
        }
        break;

      case TABLE_NAME:
        if (value == null) {
          unsetTableName();
        } else {
          setTableName((java.lang.String)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case LOGIN:
        return getLogin();

      case TABLE_NAME:
        return getTableName();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case LOGIN:
        return isSetLogin();
      case TABLE_NAME:
        return isSetTableName();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof clearLocatorCache_args)
        return this.equals((clearLocatorCache_args)that);
      return false;
    }

    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();
      if (this_present_login || that_present_login) {
        if (!(this_present_login && that_present_login))
          return false;
        if (!this.login.equals(that.login))
          return false;
      }

      boolean this_present_tableName = true && this.isSetTableName();
      boolean that_present_tableName = true && that.isSetTableName();
      if (this_present_tableName || that_present_tableName) {
        if (!(this_present_tableName && that_present_tableName))
          return false;
        if (!this.tableName.equals(that.tableName))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
      if (isSetLogin())
        hashCode = hashCode * 8191 + login.hashCode();

      hashCode = hashCode * 8191 + ((isSetTableName()) ? 131071 : 524287);
      if (isSetTableName())
        hashCode = hashCode * 8191 + tableName.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(clearLocatorCache_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLogin()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetTableName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.tableName, other.tableName);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("clearLocatorCache_args(");
      boolean first = true;

      sb.append("login:");
      if (this.login == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.login, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("tableName:");
      if (this.tableName == null) {
        sb.append("null");
      } else {
        sb.append(this.tableName);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class clearLocatorCache_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public clearLocatorCache_argsStandardScheme getScheme() {
        return new clearLocatorCache_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // LOGIN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.login = iprot.readBinary();
                struct.setLoginIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // TABLE_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.tableName = iprot.readString();
                struct.setTableNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, clearLocatorCache_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.login != null) {
          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
          oprot.writeBinary(struct.login);
          oprot.writeFieldEnd();
        }
        if (struct.tableName != null) {
          oprot.writeFieldBegin(TABLE_NAME_FIELD_DESC);
          oprot.writeString(struct.tableName);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    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 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 {
        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);
        }
        if (struct.isSetTableName()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetLogin()) {
          oprot.writeBinary(struct.login);
        }
        if (struct.isSetTableName()) {
          oprot.writeString(struct.tableName);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, clearLocatorCache_args struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.tableName = iprot.readString();
          struct.setTableNameIsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("clearLocatorCache_result");

    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);

    private static final org.apache.thrift.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

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      OUCH1((short)1, "ouch1");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // OUCH1
            return OUCH1;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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);
    }

    public clearLocatorCache_result() {
    }

    public clearLocatorCache_result(
      TableNotFoundException ouch1)
    {
      this();
      this.ouch1 = ouch1;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public clearLocatorCache_result(clearLocatorCache_result other) {
      if (other.isSetOuch1()) {
        this.ouch1 = new TableNotFoundException(other.ouch1);
      }
    }

    public clearLocatorCache_result deepCopy() {
      return new clearLocatorCache_result(this);
    }

    @Override
    public void clear() {
      this.ouch1 = null;
    }

    public TableNotFoundException getOuch1() {
      return this.ouch1;
    }

    public clearLocatorCache_result setOuch1(TableNotFoundException ouch1) {
      this.ouch1 = ouch1;
      return this;
    }

    public void unsetOuch1() {
      this.ouch1 = null;
    }

    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch1() {
      return this.ouch1 != null;
    }

    public void setOuch1IsSet(boolean value) {
      if (!value) {
        this.ouch1 = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case OUCH1:
        if (value == null) {
          unsetOuch1();
        } else {
          setOuch1((TableNotFoundException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case OUCH1:
        return getOuch1();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case OUCH1:
        return isSetOuch1();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof clearLocatorCache_result)
        return this.equals((clearLocatorCache_result)that);
      return false;
    }

    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();
      if (this_present_ouch1 || that_present_ouch1) {
        if (!(this_present_ouch1 && that_present_ouch1))
          return false;
        if (!this.ouch1.equals(that.ouch1))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
      if (isSetOuch1())
        hashCode = hashCode * 8191 + ouch1.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(clearLocatorCache_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch1()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("clearLocatorCache_result(");
      boolean first = true;

      sb.append("ouch1:");
      if (this.ouch1 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch1);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class clearLocatorCache_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public clearLocatorCache_resultStandardScheme getScheme() {
        return new clearLocatorCache_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // OUCH1
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch1 = new TableNotFoundException();
                struct.ouch1.read(iprot);
                struct.setOuch1IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, clearLocatorCache_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.ouch1 != null) {
          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
          struct.ouch1.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    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 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 {
        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);
        }
        oprot.writeBitSet(optionals, 1);
        if (struct.isSetOuch1()) {
          struct.ouch1.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, clearLocatorCache_result struct) throws org.apache.thrift.TException {
        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);
          struct.setOuch1IsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("cloneTable_args");

    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField 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 NEW_TABLE_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("newTableName", org.apache.thrift.protocol.TType.STRING, (short)3);
    private static final org.apache.thrift.protocol.TField FLUSH_FIELD_DESC = new org.apache.thrift.protocol.TField("flush", org.apache.thrift.protocol.TType.BOOL, (short)4);
    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 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 java.nio.ByteBuffer login; // required
    public java.lang.String tableName; // required
    public java.lang.String newTableName; // required
    public boolean flush; // 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 {
      LOGIN((short)1, "login"),
      TABLE_NAME((short)2, "tableName"),
      NEW_TABLE_NAME((short)3, "newTableName"),
      FLUSH((short)4, "flush"),
      PROPERTIES_TO_SET((short)5, "propertiesToSet"),
      PROPERTIES_TO_EXCLUDE((short)6, "propertiesToExclude");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // LOGIN
            return LOGIN;
          case 2: // TABLE_NAME
            return TABLE_NAME;
          case 3: // NEW_TABLE_NAME
            return NEW_TABLE_NAME;
          case 4: // FLUSH
            return FLUSH;
          case 5: // PROPERTIES_TO_SET
            return PROPERTIES_TO_SET;
          case 6: // PROPERTIES_TO_EXCLUDE
            return PROPERTIES_TO_EXCLUDE;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __FLUSH_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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)));
      tmpMap.put(_Fields.FLUSH, new org.apache.thrift.meta_data.FieldMetaData("flush", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
      tmpMap.put(_Fields.PROPERTIES_TO_SET, new org.apache.thrift.meta_data.FieldMetaData("propertiesToSet", 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.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 = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(cloneTable_args.class, metaDataMap);
    }

    public cloneTable_args() {
    }

    public cloneTable_args(
      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)
    {
      this();
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      this.tableName = tableName;
      this.newTableName = newTableName;
      this.flush = flush;
      setFlushIsSet(true);
      this.propertiesToSet = propertiesToSet;
      this.propertiesToExclude = propertiesToExclude;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public cloneTable_args(cloneTable_args other) {
      __isset_bitfield = other.__isset_bitfield;
      if (other.isSetLogin()) {
        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
      }
      if (other.isSetTableName()) {
        this.tableName = other.tableName;
      }
      if (other.isSetNewTableName()) {
        this.newTableName = other.newTableName;
      }
      this.flush = other.flush;
      if (other.isSetPropertiesToSet()) {
        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()) {
        java.util.Set<java.lang.String> __this__propertiesToExclude = new java.util.HashSet<java.lang.String>(other.propertiesToExclude);
        this.propertiesToExclude = __this__propertiesToExclude;
      }
    }

    public cloneTable_args deepCopy() {
      return new cloneTable_args(this);
    }

    @Override
    public void clear() {
      this.login = null;
      this.tableName = null;
      this.newTableName = null;
      setFlushIsSet(false);
      this.flush = false;
      this.propertiesToSet = null;
      this.propertiesToExclude = null;
    }

    public byte[] getLogin() {
      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
      return login == null ? null : login.array();
    }

    public java.nio.ByteBuffer bufferForLogin() {
      return org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    public cloneTable_args setLogin(byte[] login) {
      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
      return this;
    }

    public cloneTable_args setLogin(java.nio.ByteBuffer login) {
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      return this;
    }

    public void unsetLogin() {
      this.login = null;
    }

    /** Returns true if field login is set (has been assigned a value) and false otherwise */
    public boolean isSetLogin() {
      return this.login != null;
    }

    public void setLoginIsSet(boolean value) {
      if (!value) {
        this.login = null;
      }
    }

    public java.lang.String getTableName() {
      return this.tableName;
    }

    public cloneTable_args setTableName(java.lang.String tableName) {
      this.tableName = tableName;
      return this;
    }

    public void unsetTableName() {
      this.tableName = null;
    }

    /** Returns true if field tableName is set (has been assigned a value) and false otherwise */
    public boolean isSetTableName() {
      return this.tableName != null;
    }

    public void setTableNameIsSet(boolean value) {
      if (!value) {
        this.tableName = null;
      }
    }

    public java.lang.String getNewTableName() {
      return this.newTableName;
    }

    public cloneTable_args setNewTableName(java.lang.String newTableName) {
      this.newTableName = newTableName;
      return this;
    }

    public void unsetNewTableName() {
      this.newTableName = null;
    }

    /** Returns true if field newTableName is set (has been assigned a value) and false otherwise */
    public boolean isSetNewTableName() {
      return this.newTableName != null;
    }

    public void setNewTableNameIsSet(boolean value) {
      if (!value) {
        this.newTableName = null;
      }
    }

    public boolean isFlush() {
      return this.flush;
    }

    public cloneTable_args setFlush(boolean flush) {
      this.flush = flush;
      setFlushIsSet(true);
      return this;
    }

    public void unsetFlush() {
      __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 org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __FLUSH_ISSET_ID);
    }

    public void setFlushIsSet(boolean 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(java.lang.String key, java.lang.String val) {
      if (this.propertiesToSet == null) {
        this.propertiesToSet = new java.util.HashMap<java.lang.String,java.lang.String>();
      }
      this.propertiesToSet.put(key, val);
    }

    public java.util.Map<java.lang.String,java.lang.String> getPropertiesToSet() {
      return this.propertiesToSet;
    }

    public cloneTable_args setPropertiesToSet(java.util.Map<java.lang.String,java.lang.String> propertiesToSet) {
      this.propertiesToSet = propertiesToSet;
      return this;
    }

    public void unsetPropertiesToSet() {
      this.propertiesToSet = null;
    }

    /** Returns true if field propertiesToSet is set (has been assigned a value) and false otherwise */
    public boolean isSetPropertiesToSet() {
      return this.propertiesToSet != null;
    }

    public void setPropertiesToSetIsSet(boolean value) {
      if (!value) {
        this.propertiesToSet = null;
      }
    }

    public int getPropertiesToExcludeSize() {
      return (this.propertiesToExclude == null) ? 0 : this.propertiesToExclude.size();
    }

    public java.util.Iterator<java.lang.String> getPropertiesToExcludeIterator() {
      return (this.propertiesToExclude == null) ? null : this.propertiesToExclude.iterator();
    }

    public void addToPropertiesToExclude(java.lang.String elem) {
      if (this.propertiesToExclude == null) {
        this.propertiesToExclude = new java.util.HashSet<java.lang.String>();
      }
      this.propertiesToExclude.add(elem);
    }

    public java.util.Set<java.lang.String> getPropertiesToExclude() {
      return this.propertiesToExclude;
    }

    public cloneTable_args setPropertiesToExclude(java.util.Set<java.lang.String> propertiesToExclude) {
      this.propertiesToExclude = propertiesToExclude;
      return this;
    }

    public void unsetPropertiesToExclude() {
      this.propertiesToExclude = null;
    }

    /** Returns true if field propertiesToExclude is set (has been assigned a value) and false otherwise */
    public boolean isSetPropertiesToExclude() {
      return this.propertiesToExclude != null;
    }

    public void setPropertiesToExcludeIsSet(boolean value) {
      if (!value) {
        this.propertiesToExclude = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case LOGIN:
        if (value == null) {
          unsetLogin();
        } else {
          if (value instanceof byte[]) {
            setLogin((byte[])value);
          } else {
            setLogin((java.nio.ByteBuffer)value);
          }
        }
        break;

      case TABLE_NAME:
        if (value == null) {
          unsetTableName();
        } else {
          setTableName((java.lang.String)value);
        }
        break;

      case NEW_TABLE_NAME:
        if (value == null) {
          unsetNewTableName();
        } else {
          setNewTableName((java.lang.String)value);
        }
        break;

      case FLUSH:
        if (value == null) {
          unsetFlush();
        } else {
          setFlush((java.lang.Boolean)value);
        }
        break;

      case PROPERTIES_TO_SET:
        if (value == null) {
          unsetPropertiesToSet();
        } else {
          setPropertiesToSet((java.util.Map<java.lang.String,java.lang.String>)value);
        }
        break;

      case PROPERTIES_TO_EXCLUDE:
        if (value == null) {
          unsetPropertiesToExclude();
        } else {
          setPropertiesToExclude((java.util.Set<java.lang.String>)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case LOGIN:
        return getLogin();

      case TABLE_NAME:
        return getTableName();

      case NEW_TABLE_NAME:
        return getNewTableName();

      case FLUSH:
        return isFlush();

      case PROPERTIES_TO_SET:
        return getPropertiesToSet();

      case PROPERTIES_TO_EXCLUDE:
        return getPropertiesToExclude();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case LOGIN:
        return isSetLogin();
      case TABLE_NAME:
        return isSetTableName();
      case NEW_TABLE_NAME:
        return isSetNewTableName();
      case FLUSH:
        return isSetFlush();
      case PROPERTIES_TO_SET:
        return isSetPropertiesToSet();
      case PROPERTIES_TO_EXCLUDE:
        return isSetPropertiesToExclude();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof cloneTable_args)
        return this.equals((cloneTable_args)that);
      return false;
    }

    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();
      if (this_present_login || that_present_login) {
        if (!(this_present_login && that_present_login))
          return false;
        if (!this.login.equals(that.login))
          return false;
      }

      boolean this_present_tableName = true && this.isSetTableName();
      boolean that_present_tableName = true && that.isSetTableName();
      if (this_present_tableName || that_present_tableName) {
        if (!(this_present_tableName && that_present_tableName))
          return false;
        if (!this.tableName.equals(that.tableName))
          return false;
      }

      boolean this_present_newTableName = true && this.isSetNewTableName();
      boolean that_present_newTableName = true && that.isSetNewTableName();
      if (this_present_newTableName || that_present_newTableName) {
        if (!(this_present_newTableName && that_present_newTableName))
          return false;
        if (!this.newTableName.equals(that.newTableName))
          return false;
      }

      boolean this_present_flush = true;
      boolean that_present_flush = true;
      if (this_present_flush || that_present_flush) {
        if (!(this_present_flush && that_present_flush))
          return false;
        if (this.flush != that.flush)
          return false;
      }

      boolean this_present_propertiesToSet = true && this.isSetPropertiesToSet();
      boolean that_present_propertiesToSet = true && that.isSetPropertiesToSet();
      if (this_present_propertiesToSet || that_present_propertiesToSet) {
        if (!(this_present_propertiesToSet && that_present_propertiesToSet))
          return false;
        if (!this.propertiesToSet.equals(that.propertiesToSet))
          return false;
      }

      boolean this_present_propertiesToExclude = true && this.isSetPropertiesToExclude();
      boolean that_present_propertiesToExclude = true && that.isSetPropertiesToExclude();
      if (this_present_propertiesToExclude || that_present_propertiesToExclude) {
        if (!(this_present_propertiesToExclude && that_present_propertiesToExclude))
          return false;
        if (!this.propertiesToExclude.equals(that.propertiesToExclude))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
      if (isSetLogin())
        hashCode = hashCode * 8191 + login.hashCode();

      hashCode = hashCode * 8191 + ((isSetTableName()) ? 131071 : 524287);
      if (isSetTableName())
        hashCode = hashCode * 8191 + tableName.hashCode();

      hashCode = hashCode * 8191 + ((isSetNewTableName()) ? 131071 : 524287);
      if (isSetNewTableName())
        hashCode = hashCode * 8191 + newTableName.hashCode();

      hashCode = hashCode * 8191 + ((flush) ? 131071 : 524287);

      hashCode = hashCode * 8191 + ((isSetPropertiesToSet()) ? 131071 : 524287);
      if (isSetPropertiesToSet())
        hashCode = hashCode * 8191 + propertiesToSet.hashCode();

      hashCode = hashCode * 8191 + ((isSetPropertiesToExclude()) ? 131071 : 524287);
      if (isSetPropertiesToExclude())
        hashCode = hashCode * 8191 + propertiesToExclude.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(cloneTable_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLogin()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetTableName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.tableName, other.tableName);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetNewTableName()).compareTo(other.isSetNewTableName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetNewTableName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.newTableName, other.newTableName);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetFlush()).compareTo(other.isSetFlush());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetFlush()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.flush, other.flush);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetPropertiesToSet()).compareTo(other.isSetPropertiesToSet());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetPropertiesToSet()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.propertiesToSet, other.propertiesToSet);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetPropertiesToExclude()).compareTo(other.isSetPropertiesToExclude());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetPropertiesToExclude()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.propertiesToExclude, other.propertiesToExclude);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("cloneTable_args(");
      boolean first = true;

      sb.append("login:");
      if (this.login == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.login, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("tableName:");
      if (this.tableName == null) {
        sb.append("null");
      } else {
        sb.append(this.tableName);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("newTableName:");
      if (this.newTableName == null) {
        sb.append("null");
      } else {
        sb.append(this.newTableName);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("flush:");
      sb.append(this.flush);
      first = false;
      if (!first) sb.append(", ");
      sb.append("propertiesToSet:");
      if (this.propertiesToSet == null) {
        sb.append("null");
      } else {
        sb.append(this.propertiesToSet);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("propertiesToExclude:");
      if (this.propertiesToExclude == null) {
        sb.append("null");
      } else {
        sb.append(this.propertiesToExclude);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, 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;
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class cloneTable_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public cloneTable_argsStandardScheme getScheme() {
        return new cloneTable_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // LOGIN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.login = iprot.readBinary();
                struct.setLoginIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // TABLE_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.tableName = iprot.readString();
                struct.setTableNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // NEW_TABLE_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.newTableName = iprot.readString();
                struct.setNewTableNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // FLUSH
              if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
                struct.flush = iprot.readBool();
                struct.setFlushIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 5: // PROPERTIES_TO_SET
              if (schemeField.type == org.apache.thrift.protocol.TType.MAP) {
                {
                  org.apache.thrift.protocol.TMap _map198 = iprot.readMapBegin();
                  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();
                    _val200 = iprot.readString();
                    struct.propertiesToSet.put(_key199, _val200);
                  }
                  iprot.readMapEnd();
                }
                struct.setPropertiesToSetIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 6: // PROPERTIES_TO_EXCLUDE
              if (schemeField.type == org.apache.thrift.protocol.TType.SET) {
                {
                  org.apache.thrift.protocol.TSet _set202 = iprot.readSetBegin();
                  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();
                    struct.propertiesToExclude.add(_elem203);
                  }
                  iprot.readSetEnd();
                }
                struct.setPropertiesToExcludeIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, cloneTable_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.login != null) {
          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
          oprot.writeBinary(struct.login);
          oprot.writeFieldEnd();
        }
        if (struct.tableName != null) {
          oprot.writeFieldBegin(TABLE_NAME_FIELD_DESC);
          oprot.writeString(struct.tableName);
          oprot.writeFieldEnd();
        }
        if (struct.newTableName != null) {
          oprot.writeFieldBegin(NEW_TABLE_NAME_FIELD_DESC);
          oprot.writeString(struct.newTableName);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldBegin(FLUSH_FIELD_DESC);
        oprot.writeBool(struct.flush);
        oprot.writeFieldEnd();
        if (struct.propertiesToSet != null) {
          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 (java.util.Map.Entry<java.lang.String, java.lang.String> _iter205 : struct.propertiesToSet.entrySet())
            {
              oprot.writeString(_iter205.getKey());
              oprot.writeString(_iter205.getValue());
            }
            oprot.writeMapEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.propertiesToExclude != null) {
          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 (java.lang.String _iter206 : struct.propertiesToExclude)
            {
              oprot.writeString(_iter206);
            }
            oprot.writeSetEnd();
          }
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    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 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 {
        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);
        }
        if (struct.isSetTableName()) {
          optionals.set(1);
        }
        if (struct.isSetNewTableName()) {
          optionals.set(2);
        }
        if (struct.isSetFlush()) {
          optionals.set(3);
        }
        if (struct.isSetPropertiesToSet()) {
          optionals.set(4);
        }
        if (struct.isSetPropertiesToExclude()) {
          optionals.set(5);
        }
        oprot.writeBitSet(optionals, 6);
        if (struct.isSetLogin()) {
          oprot.writeBinary(struct.login);
        }
        if (struct.isSetTableName()) {
          oprot.writeString(struct.tableName);
        }
        if (struct.isSetNewTableName()) {
          oprot.writeString(struct.newTableName);
        }
        if (struct.isSetFlush()) {
          oprot.writeBool(struct.flush);
        }
        if (struct.isSetPropertiesToSet()) {
          {
            oprot.writeI32(struct.propertiesToSet.size());
            for (java.util.Map.Entry<java.lang.String, java.lang.String> _iter207 : struct.propertiesToSet.entrySet())
            {
              oprot.writeString(_iter207.getKey());
              oprot.writeString(_iter207.getValue());
            }
          }
        }
        if (struct.isSetPropertiesToExclude()) {
          {
            oprot.writeI32(struct.propertiesToExclude.size());
            for (java.lang.String _iter208 : struct.propertiesToExclude)
            {
              oprot.writeString(_iter208);
            }
          }
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, cloneTable_args struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.tableName = iprot.readString();
          struct.setTableNameIsSet(true);
        }
        if (incoming.get(2)) {
          struct.newTableName = iprot.readString();
          struct.setNewTableNameIsSet(true);
        }
        if (incoming.get(3)) {
          struct.flush = iprot.readBool();
          struct.setFlushIsSet(true);
        }
        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 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();
              _val211 = iprot.readString();
              struct.propertiesToSet.put(_key210, _val211);
            }
          }
          struct.setPropertiesToSetIsSet(true);
        }
        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 java.util.HashSet<java.lang.String>(2*_set213.size);
            java.lang.String _elem214;
            for (int _i215 = 0; _i215 < _set213.size; ++_i215)
            {
              _elem214 = iprot.readString();
              struct.propertiesToExclude.add(_elem214);
            }
          }
          struct.setPropertiesToExcludeIsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("cloneTable_result");

    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField OUCH3_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch3", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    private static final org.apache.thrift.protocol.TField OUCH4_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch4", org.apache.thrift.protocol.TType.STRUCT, (short)4);

    private static final 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
    public TableNotFoundException ouch3; // required
    public TableExistsException ouch4; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      OUCH1((short)1, "ouch1"),
      OUCH2((short)2, "ouch2"),
      OUCH3((short)3, "ouch3"),
      OUCH4((short)4, "ouch4");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // OUCH1
            return OUCH1;
          case 2: // OUCH2
            return OUCH2;
          case 3: // OUCH3
            return OUCH3;
          case 4: // OUCH4
            return OUCH4;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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.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.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.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);
    }

    public cloneTable_result() {
    }

    public cloneTable_result(
      AccumuloException ouch1,
      AccumuloSecurityException ouch2,
      TableNotFoundException ouch3,
      TableExistsException ouch4)
    {
      this();
      this.ouch1 = ouch1;
      this.ouch2 = ouch2;
      this.ouch3 = ouch3;
      this.ouch4 = ouch4;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public cloneTable_result(cloneTable_result other) {
      if (other.isSetOuch1()) {
        this.ouch1 = new AccumuloException(other.ouch1);
      }
      if (other.isSetOuch2()) {
        this.ouch2 = new AccumuloSecurityException(other.ouch2);
      }
      if (other.isSetOuch3()) {
        this.ouch3 = new TableNotFoundException(other.ouch3);
      }
      if (other.isSetOuch4()) {
        this.ouch4 = new TableExistsException(other.ouch4);
      }
    }

    public cloneTable_result deepCopy() {
      return new cloneTable_result(this);
    }

    @Override
    public void clear() {
      this.ouch1 = null;
      this.ouch2 = null;
      this.ouch3 = null;
      this.ouch4 = null;
    }

    public AccumuloException getOuch1() {
      return this.ouch1;
    }

    public cloneTable_result setOuch1(AccumuloException ouch1) {
      this.ouch1 = ouch1;
      return this;
    }

    public void unsetOuch1() {
      this.ouch1 = null;
    }

    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch1() {
      return this.ouch1 != null;
    }

    public void setOuch1IsSet(boolean value) {
      if (!value) {
        this.ouch1 = null;
      }
    }

    public AccumuloSecurityException getOuch2() {
      return this.ouch2;
    }

    public cloneTable_result setOuch2(AccumuloSecurityException ouch2) {
      this.ouch2 = ouch2;
      return this;
    }

    public void unsetOuch2() {
      this.ouch2 = null;
    }

    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch2() {
      return this.ouch2 != null;
    }

    public void setOuch2IsSet(boolean value) {
      if (!value) {
        this.ouch2 = null;
      }
    }

    public TableNotFoundException getOuch3() {
      return this.ouch3;
    }

    public cloneTable_result setOuch3(TableNotFoundException ouch3) {
      this.ouch3 = ouch3;
      return this;
    }

    public void unsetOuch3() {
      this.ouch3 = null;
    }

    /** Returns true if field ouch3 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch3() {
      return this.ouch3 != null;
    }

    public void setOuch3IsSet(boolean value) {
      if (!value) {
        this.ouch3 = null;
      }
    }

    public TableExistsException getOuch4() {
      return this.ouch4;
    }

    public cloneTable_result setOuch4(TableExistsException ouch4) {
      this.ouch4 = ouch4;
      return this;
    }

    public void unsetOuch4() {
      this.ouch4 = null;
    }

    /** Returns true if field ouch4 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch4() {
      return this.ouch4 != null;
    }

    public void setOuch4IsSet(boolean value) {
      if (!value) {
        this.ouch4 = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case OUCH1:
        if (value == null) {
          unsetOuch1();
        } else {
          setOuch1((AccumuloException)value);
        }
        break;

      case OUCH2:
        if (value == null) {
          unsetOuch2();
        } else {
          setOuch2((AccumuloSecurityException)value);
        }
        break;

      case OUCH3:
        if (value == null) {
          unsetOuch3();
        } else {
          setOuch3((TableNotFoundException)value);
        }
        break;

      case OUCH4:
        if (value == null) {
          unsetOuch4();
        } else {
          setOuch4((TableExistsException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case OUCH1:
        return getOuch1();

      case OUCH2:
        return getOuch2();

      case OUCH3:
        return getOuch3();

      case OUCH4:
        return getOuch4();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case OUCH1:
        return isSetOuch1();
      case OUCH2:
        return isSetOuch2();
      case OUCH3:
        return isSetOuch3();
      case OUCH4:
        return isSetOuch4();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof cloneTable_result)
        return this.equals((cloneTable_result)that);
      return false;
    }

    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();
      if (this_present_ouch1 || that_present_ouch1) {
        if (!(this_present_ouch1 && that_present_ouch1))
          return false;
        if (!this.ouch1.equals(that.ouch1))
          return false;
      }

      boolean this_present_ouch2 = true && this.isSetOuch2();
      boolean that_present_ouch2 = true && that.isSetOuch2();
      if (this_present_ouch2 || that_present_ouch2) {
        if (!(this_present_ouch2 && that_present_ouch2))
          return false;
        if (!this.ouch2.equals(that.ouch2))
          return false;
      }

      boolean this_present_ouch3 = true && this.isSetOuch3();
      boolean that_present_ouch3 = true && that.isSetOuch3();
      if (this_present_ouch3 || that_present_ouch3) {
        if (!(this_present_ouch3 && that_present_ouch3))
          return false;
        if (!this.ouch3.equals(that.ouch3))
          return false;
      }

      boolean this_present_ouch4 = true && this.isSetOuch4();
      boolean that_present_ouch4 = true && that.isSetOuch4();
      if (this_present_ouch4 || that_present_ouch4) {
        if (!(this_present_ouch4 && that_present_ouch4))
          return false;
        if (!this.ouch4.equals(that.ouch4))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
      if (isSetOuch1())
        hashCode = hashCode * 8191 + ouch1.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
      if (isSetOuch2())
        hashCode = hashCode * 8191 + ouch2.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
      if (isSetOuch3())
        hashCode = hashCode * 8191 + ouch3.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch4()) ? 131071 : 524287);
      if (isSetOuch4())
        hashCode = hashCode * 8191 + ouch4.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(cloneTable_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch1()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch2()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch3()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch3, other.ouch3);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch4()).compareTo(other.isSetOuch4());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch4()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch4, other.ouch4);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("cloneTable_result(");
      boolean first = true;

      sb.append("ouch1:");
      if (this.ouch1 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch1);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch2:");
      if (this.ouch2 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch2);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch3:");
      if (this.ouch3 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch3);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch4:");
      if (this.ouch4 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch4);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class cloneTable_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public cloneTable_resultStandardScheme getScheme() {
        return new cloneTable_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // OUCH1
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch1 = new AccumuloException();
                struct.ouch1.read(iprot);
                struct.setOuch1IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OUCH2
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch2 = new AccumuloSecurityException();
                struct.ouch2.read(iprot);
                struct.setOuch2IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // OUCH3
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch3 = new TableNotFoundException();
                struct.ouch3.read(iprot);
                struct.setOuch3IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // OUCH4
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch4 = new TableExistsException();
                struct.ouch4.read(iprot);
                struct.setOuch4IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, cloneTable_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.ouch1 != null) {
          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
          struct.ouch1.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch2 != null) {
          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
          struct.ouch2.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch3 != null) {
          oprot.writeFieldBegin(OUCH3_FIELD_DESC);
          struct.ouch3.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch4 != null) {
          oprot.writeFieldBegin(OUCH4_FIELD_DESC);
          struct.ouch4.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class cloneTable_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public cloneTable_resultTupleScheme getScheme() {
        return new cloneTable_resultTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetOuch2()) {
          optionals.set(1);
        }
        if (struct.isSetOuch3()) {
          optionals.set(2);
        }
        if (struct.isSetOuch4()) {
          optionals.set(3);
        }
        oprot.writeBitSet(optionals, 4);
        if (struct.isSetOuch1()) {
          struct.ouch1.write(oprot);
        }
        if (struct.isSetOuch2()) {
          struct.ouch2.write(oprot);
        }
        if (struct.isSetOuch3()) {
          struct.ouch3.write(oprot);
        }
        if (struct.isSetOuch4()) {
          struct.ouch4.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, cloneTable_result struct) throws org.apache.thrift.TException {
        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);
          struct.setOuch1IsSet(true);
        }
        if (incoming.get(1)) {
          struct.ouch2 = new AccumuloSecurityException();
          struct.ouch2.read(iprot);
          struct.setOuch2IsSet(true);
        }
        if (incoming.get(2)) {
          struct.ouch3 = new TableNotFoundException();
          struct.ouch3.read(iprot);
          struct.setOuch3IsSet(true);
        }
        if (incoming.get(3)) {
          struct.ouch4 = new TableExistsException();
          struct.ouch4.read(iprot);
          struct.setOuch4IsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("compactTable_args");

    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField 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 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 org.apache.thrift.protocol.TField ITERATORS_FIELD_DESC = new org.apache.thrift.protocol.TField("iterators", org.apache.thrift.protocol.TType.LIST, (short)5);
    private static final org.apache.thrift.protocol.TField FLUSH_FIELD_DESC = new org.apache.thrift.protocol.TField("flush", org.apache.thrift.protocol.TType.BOOL, (short)6);
    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 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 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

    /** 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"),
      START_ROW((short)3, "startRow"),
      END_ROW((short)4, "endRow"),
      ITERATORS((short)5, "iterators"),
      FLUSH((short)6, "flush"),
      WAIT((short)7, "wait"),
      COMPACTION_STRATEGY((short)8, "compactionStrategy");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // LOGIN
            return LOGIN;
          case 2: // TABLE_NAME
            return TABLE_NAME;
          case 3: // START_ROW
            return START_ROW;
          case 4: // END_ROW
            return END_ROW;
          case 5: // ITERATORS
            return ITERATORS;
          case 6: // FLUSH
            return FLUSH;
          case 7: // WAIT
            return WAIT;
          case 8: // COMPACTION_STRATEGY
            return COMPACTION_STRATEGY;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __FLUSH_ISSET_ID = 0;
    private static final int __WAIT_ISSET_ID = 1;
    private byte __isset_bitfield = 0;
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.START_ROW, new org.apache.thrift.meta_data.FieldMetaData("startRow", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          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)));
      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))));
      tmpMap.put(_Fields.FLUSH, new org.apache.thrift.meta_data.FieldMetaData("flush", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
      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)));
      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 = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(compactTable_args.class, metaDataMap);
    }

    public compactTable_args() {
    }

    public compactTable_args(
      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)
    {
      this();
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      this.tableName = tableName;
      this.startRow = org.apache.thrift.TBaseHelper.copyBinary(startRow);
      this.endRow = org.apache.thrift.TBaseHelper.copyBinary(endRow);
      this.iterators = iterators;
      this.flush = flush;
      setFlushIsSet(true);
      this.wait = wait;
      setWaitIsSet(true);
      this.compactionStrategy = compactionStrategy;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public compactTable_args(compactTable_args other) {
      __isset_bitfield = other.__isset_bitfield;
      if (other.isSetLogin()) {
        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
      }
      if (other.isSetTableName()) {
        this.tableName = other.tableName;
      }
      if (other.isSetStartRow()) {
        this.startRow = org.apache.thrift.TBaseHelper.copyBinary(other.startRow);
      }
      if (other.isSetEndRow()) {
        this.endRow = org.apache.thrift.TBaseHelper.copyBinary(other.endRow);
      }
      if (other.isSetIterators()) {
        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;
      }
      this.flush = other.flush;
      this.wait = other.wait;
      if (other.isSetCompactionStrategy()) {
        this.compactionStrategy = new CompactionStrategyConfig(other.compactionStrategy);
      }
    }

    public compactTable_args deepCopy() {
      return new compactTable_args(this);
    }

    @Override
    public void clear() {
      this.login = null;
      this.tableName = null;
      this.startRow = null;
      this.endRow = null;
      this.iterators = null;
      setFlushIsSet(false);
      this.flush = false;
      setWaitIsSet(false);
      this.wait = false;
      this.compactionStrategy = null;
    }

    public byte[] getLogin() {
      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
      return login == null ? null : login.array();
    }

    public java.nio.ByteBuffer bufferForLogin() {
      return org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    public compactTable_args setLogin(byte[] login) {
      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
      return this;
    }

    public compactTable_args setLogin(java.nio.ByteBuffer login) {
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      return this;
    }

    public void unsetLogin() {
      this.login = null;
    }

    /** Returns true if field login is set (has been assigned a value) and false otherwise */
    public boolean isSetLogin() {
      return this.login != null;
    }

    public void setLoginIsSet(boolean value) {
      if (!value) {
        this.login = null;
      }
    }

    public java.lang.String getTableName() {
      return this.tableName;
    }

    public compactTable_args setTableName(java.lang.String tableName) {
      this.tableName = tableName;
      return this;
    }

    public void unsetTableName() {
      this.tableName = null;
    }

    /** Returns true if field tableName is set (has been assigned a value) and false otherwise */
    public boolean isSetTableName() {
      return this.tableName != null;
    }

    public void setTableNameIsSet(boolean value) {
      if (!value) {
        this.tableName = null;
      }
    }

    public byte[] getStartRow() {
      setStartRow(org.apache.thrift.TBaseHelper.rightSize(startRow));
      return startRow == null ? null : startRow.array();
    }

    public java.nio.ByteBuffer bufferForStartRow() {
      return org.apache.thrift.TBaseHelper.copyBinary(startRow);
    }

    public compactTable_args setStartRow(byte[] startRow) {
      this.startRow = startRow == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(startRow.clone());
      return this;
    }

    public compactTable_args setStartRow(java.nio.ByteBuffer startRow) {
      this.startRow = org.apache.thrift.TBaseHelper.copyBinary(startRow);
      return this;
    }

    public void unsetStartRow() {
      this.startRow = null;
    }

    /** Returns true if field startRow is set (has been assigned a value) and false otherwise */
    public boolean isSetStartRow() {
      return this.startRow != null;
    }

    public void setStartRowIsSet(boolean value) {
      if (!value) {
        this.startRow = null;
      }
    }

    public byte[] getEndRow() {
      setEndRow(org.apache.thrift.TBaseHelper.rightSize(endRow));
      return endRow == null ? null : endRow.array();
    }

    public java.nio.ByteBuffer bufferForEndRow() {
      return org.apache.thrift.TBaseHelper.copyBinary(endRow);
    }

    public compactTable_args setEndRow(byte[] endRow) {
      this.endRow = endRow == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(endRow.clone());
      return this;
    }

    public compactTable_args setEndRow(java.nio.ByteBuffer endRow) {
      this.endRow = org.apache.thrift.TBaseHelper.copyBinary(endRow);
      return this;
    }

    public void unsetEndRow() {
      this.endRow = null;
    }

    /** Returns true if field endRow is set (has been assigned a value) and false otherwise */
    public boolean isSetEndRow() {
      return this.endRow != null;
    }

    public void setEndRowIsSet(boolean value) {
      if (!value) {
        this.endRow = null;
      }
    }

    public int getIteratorsSize() {
      return (this.iterators == null) ? 0 : this.iterators.size();
    }

    public java.util.Iterator<IteratorSetting> getIteratorsIterator() {
      return (this.iterators == null) ? null : this.iterators.iterator();
    }

    public void addToIterators(IteratorSetting elem) {
      if (this.iterators == null) {
        this.iterators = new java.util.ArrayList<IteratorSetting>();
      }
      this.iterators.add(elem);
    }

    public java.util.List<IteratorSetting> getIterators() {
      return this.iterators;
    }

    public compactTable_args setIterators(java.util.List<IteratorSetting> iterators) {
      this.iterators = iterators;
      return this;
    }

    public void unsetIterators() {
      this.iterators = null;
    }

    /** Returns true if field iterators is set (has been assigned a value) and false otherwise */
    public boolean isSetIterators() {
      return this.iterators != null;
    }

    public void setIteratorsIsSet(boolean value) {
      if (!value) {
        this.iterators = null;
      }
    }

    public boolean isFlush() {
      return this.flush;
    }

    public compactTable_args setFlush(boolean flush) {
      this.flush = flush;
      setFlushIsSet(true);
      return this;
    }

    public void unsetFlush() {
      __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 org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __FLUSH_ISSET_ID);
    }

    public void setFlushIsSet(boolean value) {
      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __FLUSH_ISSET_ID, value);
    }

    public boolean isWait() {
      return this.wait;
    }

    public compactTable_args setWait(boolean wait) {
      this.wait = wait;
      setWaitIsSet(true);
      return this;
    }

    public void unsetWait() {
      __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 org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __WAIT_ISSET_ID);
    }

    public void setWaitIsSet(boolean value) {
      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __WAIT_ISSET_ID, value);
    }

    public CompactionStrategyConfig getCompactionStrategy() {
      return this.compactionStrategy;
    }

    public compactTable_args setCompactionStrategy(CompactionStrategyConfig compactionStrategy) {
      this.compactionStrategy = compactionStrategy;
      return this;
    }

    public void unsetCompactionStrategy() {
      this.compactionStrategy = null;
    }

    /** Returns true if field compactionStrategy is set (has been assigned a value) and false otherwise */
    public boolean isSetCompactionStrategy() {
      return this.compactionStrategy != null;
    }

    public void setCompactionStrategyIsSet(boolean value) {
      if (!value) {
        this.compactionStrategy = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case LOGIN:
        if (value == null) {
          unsetLogin();
        } else {
          if (value instanceof byte[]) {
            setLogin((byte[])value);
          } else {
            setLogin((java.nio.ByteBuffer)value);
          }
        }
        break;

      case TABLE_NAME:
        if (value == null) {
          unsetTableName();
        } else {
          setTableName((java.lang.String)value);
        }
        break;

      case START_ROW:
        if (value == null) {
          unsetStartRow();
        } else {
          if (value instanceof byte[]) {
            setStartRow((byte[])value);
          } else {
            setStartRow((java.nio.ByteBuffer)value);
          }
        }
        break;

      case END_ROW:
        if (value == null) {
          unsetEndRow();
        } else {
          if (value instanceof byte[]) {
            setEndRow((byte[])value);
          } else {
            setEndRow((java.nio.ByteBuffer)value);
          }
        }
        break;

      case ITERATORS:
        if (value == null) {
          unsetIterators();
        } else {
          setIterators((java.util.List<IteratorSetting>)value);
        }
        break;

      case FLUSH:
        if (value == null) {
          unsetFlush();
        } else {
          setFlush((java.lang.Boolean)value);
        }
        break;

      case WAIT:
        if (value == null) {
          unsetWait();
        } else {
          setWait((java.lang.Boolean)value);
        }
        break;

      case COMPACTION_STRATEGY:
        if (value == null) {
          unsetCompactionStrategy();
        } else {
          setCompactionStrategy((CompactionStrategyConfig)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case LOGIN:
        return getLogin();

      case TABLE_NAME:
        return getTableName();

      case START_ROW:
        return getStartRow();

      case END_ROW:
        return getEndRow();

      case ITERATORS:
        return getIterators();

      case FLUSH:
        return isFlush();

      case WAIT:
        return isWait();

      case COMPACTION_STRATEGY:
        return getCompactionStrategy();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case LOGIN:
        return isSetLogin();
      case TABLE_NAME:
        return isSetTableName();
      case START_ROW:
        return isSetStartRow();
      case END_ROW:
        return isSetEndRow();
      case ITERATORS:
        return isSetIterators();
      case FLUSH:
        return isSetFlush();
      case WAIT:
        return isSetWait();
      case COMPACTION_STRATEGY:
        return isSetCompactionStrategy();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof compactTable_args)
        return this.equals((compactTable_args)that);
      return false;
    }

    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();
      if (this_present_login || that_present_login) {
        if (!(this_present_login && that_present_login))
          return false;
        if (!this.login.equals(that.login))
          return false;
      }

      boolean this_present_tableName = true && this.isSetTableName();
      boolean that_present_tableName = true && that.isSetTableName();
      if (this_present_tableName || that_present_tableName) {
        if (!(this_present_tableName && that_present_tableName))
          return false;
        if (!this.tableName.equals(that.tableName))
          return false;
      }

      boolean this_present_startRow = true && this.isSetStartRow();
      boolean that_present_startRow = true && that.isSetStartRow();
      if (this_present_startRow || that_present_startRow) {
        if (!(this_present_startRow && that_present_startRow))
          return false;
        if (!this.startRow.equals(that.startRow))
          return false;
      }

      boolean this_present_endRow = true && this.isSetEndRow();
      boolean that_present_endRow = true && that.isSetEndRow();
      if (this_present_endRow || that_present_endRow) {
        if (!(this_present_endRow && that_present_endRow))
          return false;
        if (!this.endRow.equals(that.endRow))
          return false;
      }

      boolean this_present_iterators = true && this.isSetIterators();
      boolean that_present_iterators = true && that.isSetIterators();
      if (this_present_iterators || that_present_iterators) {
        if (!(this_present_iterators && that_present_iterators))
          return false;
        if (!this.iterators.equals(that.iterators))
          return false;
      }

      boolean this_present_flush = true;
      boolean that_present_flush = true;
      if (this_present_flush || that_present_flush) {
        if (!(this_present_flush && that_present_flush))
          return false;
        if (this.flush != that.flush)
          return false;
      }

      boolean this_present_wait = true;
      boolean that_present_wait = true;
      if (this_present_wait || that_present_wait) {
        if (!(this_present_wait && that_present_wait))
          return false;
        if (this.wait != that.wait)
          return false;
      }

      boolean this_present_compactionStrategy = true && this.isSetCompactionStrategy();
      boolean that_present_compactionStrategy = true && that.isSetCompactionStrategy();
      if (this_present_compactionStrategy || that_present_compactionStrategy) {
        if (!(this_present_compactionStrategy && that_present_compactionStrategy))
          return false;
        if (!this.compactionStrategy.equals(that.compactionStrategy))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
      if (isSetLogin())
        hashCode = hashCode * 8191 + login.hashCode();

      hashCode = hashCode * 8191 + ((isSetTableName()) ? 131071 : 524287);
      if (isSetTableName())
        hashCode = hashCode * 8191 + tableName.hashCode();

      hashCode = hashCode * 8191 + ((isSetStartRow()) ? 131071 : 524287);
      if (isSetStartRow())
        hashCode = hashCode * 8191 + startRow.hashCode();

      hashCode = hashCode * 8191 + ((isSetEndRow()) ? 131071 : 524287);
      if (isSetEndRow())
        hashCode = hashCode * 8191 + endRow.hashCode();

      hashCode = hashCode * 8191 + ((isSetIterators()) ? 131071 : 524287);
      if (isSetIterators())
        hashCode = hashCode * 8191 + iterators.hashCode();

      hashCode = hashCode * 8191 + ((flush) ? 131071 : 524287);

      hashCode = hashCode * 8191 + ((wait) ? 131071 : 524287);

      hashCode = hashCode * 8191 + ((isSetCompactionStrategy()) ? 131071 : 524287);
      if (isSetCompactionStrategy())
        hashCode = hashCode * 8191 + compactionStrategy.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(compactTable_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLogin()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetTableName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.tableName, other.tableName);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetStartRow()).compareTo(other.isSetStartRow());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetStartRow()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.startRow, other.startRow);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetEndRow()).compareTo(other.isSetEndRow());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetEndRow()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.endRow, other.endRow);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetIterators()).compareTo(other.isSetIterators());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIterators()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.iterators, other.iterators);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetFlush()).compareTo(other.isSetFlush());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetFlush()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.flush, other.flush);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetWait()).compareTo(other.isSetWait());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetWait()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.wait, other.wait);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetCompactionStrategy()).compareTo(other.isSetCompactionStrategy());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetCompactionStrategy()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.compactionStrategy, other.compactionStrategy);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("compactTable_args(");
      boolean first = true;

      sb.append("login:");
      if (this.login == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.login, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("tableName:");
      if (this.tableName == null) {
        sb.append("null");
      } else {
        sb.append(this.tableName);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("startRow:");
      if (this.startRow == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.startRow, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("endRow:");
      if (this.endRow == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.endRow, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("iterators:");
      if (this.iterators == null) {
        sb.append("null");
      } else {
        sb.append(this.iterators);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("flush:");
      sb.append(this.flush);
      first = false;
      if (!first) sb.append(", ");
      sb.append("wait:");
      sb.append(this.wait);
      first = false;
      if (!first) sb.append(", ");
      sb.append("compactionStrategy:");
      if (this.compactionStrategy == null) {
        sb.append("null");
      } else {
        sb.append(this.compactionStrategy);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
      if (compactionStrategy != null) {
        compactionStrategy.validate();
      }
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, 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;
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class compactTable_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public compactTable_argsStandardScheme getScheme() {
        return new compactTable_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // LOGIN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.login = iprot.readBinary();
                struct.setLoginIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // TABLE_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.tableName = iprot.readString();
                struct.setTableNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // START_ROW
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.startRow = iprot.readBinary();
                struct.setStartRowIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // END_ROW
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.endRow = iprot.readBinary();
                struct.setEndRowIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 5: // ITERATORS
              if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
                {
                  org.apache.thrift.protocol.TList _list216 = iprot.readListBegin();
                  struct.iterators = new java.util.ArrayList<IteratorSetting>(_list216.size);
                  IteratorSetting _elem217;
                  for (int _i218 = 0; _i218 < _list216.size; ++_i218)
                  {
                    _elem217 = new IteratorSetting();
                    _elem217.read(iprot);
                    struct.iterators.add(_elem217);
                  }
                  iprot.readListEnd();
                }
                struct.setIteratorsIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 6: // FLUSH
              if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
                struct.flush = iprot.readBool();
                struct.setFlushIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 7: // WAIT
              if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
                struct.wait = iprot.readBool();
                struct.setWaitIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 8: // COMPACTION_STRATEGY
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.compactionStrategy = new CompactionStrategyConfig();
                struct.compactionStrategy.read(iprot);
                struct.setCompactionStrategyIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, compactTable_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.login != null) {
          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
          oprot.writeBinary(struct.login);
          oprot.writeFieldEnd();
        }
        if (struct.tableName != null) {
          oprot.writeFieldBegin(TABLE_NAME_FIELD_DESC);
          oprot.writeString(struct.tableName);
          oprot.writeFieldEnd();
        }
        if (struct.startRow != null) {
          oprot.writeFieldBegin(START_ROW_FIELD_DESC);
          oprot.writeBinary(struct.startRow);
          oprot.writeFieldEnd();
        }
        if (struct.endRow != null) {
          oprot.writeFieldBegin(END_ROW_FIELD_DESC);
          oprot.writeBinary(struct.endRow);
          oprot.writeFieldEnd();
        }
        if (struct.iterators != null) {
          oprot.writeFieldBegin(ITERATORS_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, struct.iterators.size()));
            for (IteratorSetting _iter219 : struct.iterators)
            {
              _iter219.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
        oprot.writeFieldBegin(FLUSH_FIELD_DESC);
        oprot.writeBool(struct.flush);
        oprot.writeFieldEnd();
        oprot.writeFieldBegin(WAIT_FIELD_DESC);
        oprot.writeBool(struct.wait);
        oprot.writeFieldEnd();
        if (struct.compactionStrategy != null) {
          oprot.writeFieldBegin(COMPACTION_STRATEGY_FIELD_DESC);
          struct.compactionStrategy.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    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 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 {
        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);
        }
        if (struct.isSetTableName()) {
          optionals.set(1);
        }
        if (struct.isSetStartRow()) {
          optionals.set(2);
        }
        if (struct.isSetEndRow()) {
          optionals.set(3);
        }
        if (struct.isSetIterators()) {
          optionals.set(4);
        }
        if (struct.isSetFlush()) {
          optionals.set(5);
        }
        if (struct.isSetWait()) {
          optionals.set(6);
        }
        if (struct.isSetCompactionStrategy()) {
          optionals.set(7);
        }
        oprot.writeBitSet(optionals, 8);
        if (struct.isSetLogin()) {
          oprot.writeBinary(struct.login);
        }
        if (struct.isSetTableName()) {
          oprot.writeString(struct.tableName);
        }
        if (struct.isSetStartRow()) {
          oprot.writeBinary(struct.startRow);
        }
        if (struct.isSetEndRow()) {
          oprot.writeBinary(struct.endRow);
        }
        if (struct.isSetIterators()) {
          {
            oprot.writeI32(struct.iterators.size());
            for (IteratorSetting _iter220 : struct.iterators)
            {
              _iter220.write(oprot);
            }
          }
        }
        if (struct.isSetFlush()) {
          oprot.writeBool(struct.flush);
        }
        if (struct.isSetWait()) {
          oprot.writeBool(struct.wait);
        }
        if (struct.isSetCompactionStrategy()) {
          struct.compactionStrategy.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, compactTable_args struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.tableName = iprot.readString();
          struct.setTableNameIsSet(true);
        }
        if (incoming.get(2)) {
          struct.startRow = iprot.readBinary();
          struct.setStartRowIsSet(true);
        }
        if (incoming.get(3)) {
          struct.endRow = iprot.readBinary();
          struct.setEndRowIsSet(true);
        }
        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 java.util.ArrayList<IteratorSetting>(_list221.size);
            IteratorSetting _elem222;
            for (int _i223 = 0; _i223 < _list221.size; ++_i223)
            {
              _elem222 = new IteratorSetting();
              _elem222.read(iprot);
              struct.iterators.add(_elem222);
            }
          }
          struct.setIteratorsIsSet(true);
        }
        if (incoming.get(5)) {
          struct.flush = iprot.readBool();
          struct.setFlushIsSet(true);
        }
        if (incoming.get(6)) {
          struct.wait = iprot.readBool();
          struct.setWaitIsSet(true);
        }
        if (incoming.get(7)) {
          struct.compactionStrategy = new CompactionStrategyConfig();
          struct.compactionStrategy.read(iprot);
          struct.setCompactionStrategyIsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("compactTable_result");

    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField OUCH3_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch3", org.apache.thrift.protocol.TType.STRUCT, (short)3);

    private static final org.apache.thrift.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
    public AccumuloException ouch3; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      OUCH1((short)1, "ouch1"),
      OUCH2((short)2, "ouch2"),
      OUCH3((short)3, "ouch3");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // OUCH1
            return OUCH1;
          case 2: // OUCH2
            return OUCH2;
          case 3: // OUCH3
            return OUCH3;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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.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.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);
    }

    public compactTable_result() {
    }

    public compactTable_result(
      AccumuloSecurityException ouch1,
      TableNotFoundException ouch2,
      AccumuloException ouch3)
    {
      this();
      this.ouch1 = ouch1;
      this.ouch2 = ouch2;
      this.ouch3 = ouch3;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public compactTable_result(compactTable_result other) {
      if (other.isSetOuch1()) {
        this.ouch1 = new AccumuloSecurityException(other.ouch1);
      }
      if (other.isSetOuch2()) {
        this.ouch2 = new TableNotFoundException(other.ouch2);
      }
      if (other.isSetOuch3()) {
        this.ouch3 = new AccumuloException(other.ouch3);
      }
    }

    public compactTable_result deepCopy() {
      return new compactTable_result(this);
    }

    @Override
    public void clear() {
      this.ouch1 = null;
      this.ouch2 = null;
      this.ouch3 = null;
    }

    public AccumuloSecurityException getOuch1() {
      return this.ouch1;
    }

    public compactTable_result setOuch1(AccumuloSecurityException ouch1) {
      this.ouch1 = ouch1;
      return this;
    }

    public void unsetOuch1() {
      this.ouch1 = null;
    }

    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch1() {
      return this.ouch1 != null;
    }

    public void setOuch1IsSet(boolean value) {
      if (!value) {
        this.ouch1 = null;
      }
    }

    public TableNotFoundException getOuch2() {
      return this.ouch2;
    }

    public compactTable_result setOuch2(TableNotFoundException ouch2) {
      this.ouch2 = ouch2;
      return this;
    }

    public void unsetOuch2() {
      this.ouch2 = null;
    }

    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch2() {
      return this.ouch2 != null;
    }

    public void setOuch2IsSet(boolean value) {
      if (!value) {
        this.ouch2 = null;
      }
    }

    public AccumuloException getOuch3() {
      return this.ouch3;
    }

    public compactTable_result setOuch3(AccumuloException ouch3) {
      this.ouch3 = ouch3;
      return this;
    }

    public void unsetOuch3() {
      this.ouch3 = null;
    }

    /** Returns true if field ouch3 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch3() {
      return this.ouch3 != null;
    }

    public void setOuch3IsSet(boolean value) {
      if (!value) {
        this.ouch3 = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case OUCH1:
        if (value == null) {
          unsetOuch1();
        } else {
          setOuch1((AccumuloSecurityException)value);
        }
        break;

      case OUCH2:
        if (value == null) {
          unsetOuch2();
        } else {
          setOuch2((TableNotFoundException)value);
        }
        break;

      case OUCH3:
        if (value == null) {
          unsetOuch3();
        } else {
          setOuch3((AccumuloException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case OUCH1:
        return getOuch1();

      case OUCH2:
        return getOuch2();

      case OUCH3:
        return getOuch3();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case OUCH1:
        return isSetOuch1();
      case OUCH2:
        return isSetOuch2();
      case OUCH3:
        return isSetOuch3();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof compactTable_result)
        return this.equals((compactTable_result)that);
      return false;
    }

    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();
      if (this_present_ouch1 || that_present_ouch1) {
        if (!(this_present_ouch1 && that_present_ouch1))
          return false;
        if (!this.ouch1.equals(that.ouch1))
          return false;
      }

      boolean this_present_ouch2 = true && this.isSetOuch2();
      boolean that_present_ouch2 = true && that.isSetOuch2();
      if (this_present_ouch2 || that_present_ouch2) {
        if (!(this_present_ouch2 && that_present_ouch2))
          return false;
        if (!this.ouch2.equals(that.ouch2))
          return false;
      }

      boolean this_present_ouch3 = true && this.isSetOuch3();
      boolean that_present_ouch3 = true && that.isSetOuch3();
      if (this_present_ouch3 || that_present_ouch3) {
        if (!(this_present_ouch3 && that_present_ouch3))
          return false;
        if (!this.ouch3.equals(that.ouch3))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
      if (isSetOuch1())
        hashCode = hashCode * 8191 + ouch1.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
      if (isSetOuch2())
        hashCode = hashCode * 8191 + ouch2.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
      if (isSetOuch3())
        hashCode = hashCode * 8191 + ouch3.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(compactTable_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch1()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch2()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch3()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch3, other.ouch3);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("compactTable_result(");
      boolean first = true;

      sb.append("ouch1:");
      if (this.ouch1 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch1);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch2:");
      if (this.ouch2 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch2);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch3:");
      if (this.ouch3 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch3);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class compactTable_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public compactTable_resultStandardScheme getScheme() {
        return new compactTable_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // OUCH1
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch1 = new AccumuloSecurityException();
                struct.ouch1.read(iprot);
                struct.setOuch1IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OUCH2
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch2 = new TableNotFoundException();
                struct.ouch2.read(iprot);
                struct.setOuch2IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // OUCH3
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch3 = new AccumuloException();
                struct.ouch3.read(iprot);
                struct.setOuch3IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, compactTable_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.ouch1 != null) {
          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
          struct.ouch1.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch2 != null) {
          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
          struct.ouch2.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch3 != null) {
          oprot.writeFieldBegin(OUCH3_FIELD_DESC);
          struct.ouch3.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class compactTable_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public compactTable_resultTupleScheme getScheme() {
        return new compactTable_resultTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetOuch2()) {
          optionals.set(1);
        }
        if (struct.isSetOuch3()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetOuch1()) {
          struct.ouch1.write(oprot);
        }
        if (struct.isSetOuch2()) {
          struct.ouch2.write(oprot);
        }
        if (struct.isSetOuch3()) {
          struct.ouch3.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, compactTable_result struct) throws org.apache.thrift.TException {
        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);
          struct.setOuch1IsSet(true);
        }
        if (incoming.get(1)) {
          struct.ouch2 = new TableNotFoundException();
          struct.ouch2.read(iprot);
          struct.setOuch2IsSet(true);
        }
        if (incoming.get(2)) {
          struct.ouch3 = new AccumuloException();
          struct.ouch3.read(iprot);
          struct.setOuch3IsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("cancelCompaction_args");

    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField 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.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new cancelCompaction_argsStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new cancelCompaction_argsTupleSchemeFactory();

    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 java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // LOGIN
            return LOGIN;
          case 2: // TABLE_NAME
            return TABLE_NAME;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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 = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(cancelCompaction_args.class, metaDataMap);
    }

    public cancelCompaction_args() {
    }

    public cancelCompaction_args(
      java.nio.ByteBuffer login,
      java.lang.String tableName)
    {
      this();
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      this.tableName = tableName;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public cancelCompaction_args(cancelCompaction_args other) {
      if (other.isSetLogin()) {
        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
      }
      if (other.isSetTableName()) {
        this.tableName = other.tableName;
      }
    }

    public cancelCompaction_args deepCopy() {
      return new cancelCompaction_args(this);
    }

    @Override
    public void clear() {
      this.login = null;
      this.tableName = null;
    }

    public byte[] getLogin() {
      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
      return login == null ? null : login.array();
    }

    public java.nio.ByteBuffer bufferForLogin() {
      return org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    public cancelCompaction_args setLogin(byte[] login) {
      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
      return this;
    }

    public cancelCompaction_args setLogin(java.nio.ByteBuffer login) {
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      return this;
    }

    public void unsetLogin() {
      this.login = null;
    }

    /** Returns true if field login is set (has been assigned a value) and false otherwise */
    public boolean isSetLogin() {
      return this.login != null;
    }

    public void setLoginIsSet(boolean value) {
      if (!value) {
        this.login = null;
      }
    }

    public java.lang.String getTableName() {
      return this.tableName;
    }

    public cancelCompaction_args setTableName(java.lang.String tableName) {
      this.tableName = tableName;
      return this;
    }

    public void unsetTableName() {
      this.tableName = null;
    }

    /** Returns true if field tableName is set (has been assigned a value) and false otherwise */
    public boolean isSetTableName() {
      return this.tableName != null;
    }

    public void setTableNameIsSet(boolean value) {
      if (!value) {
        this.tableName = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case LOGIN:
        if (value == null) {
          unsetLogin();
        } else {
          if (value instanceof byte[]) {
            setLogin((byte[])value);
          } else {
            setLogin((java.nio.ByteBuffer)value);
          }
        }
        break;

      case TABLE_NAME:
        if (value == null) {
          unsetTableName();
        } else {
          setTableName((java.lang.String)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case LOGIN:
        return getLogin();

      case TABLE_NAME:
        return getTableName();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case LOGIN:
        return isSetLogin();
      case TABLE_NAME:
        return isSetTableName();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof cancelCompaction_args)
        return this.equals((cancelCompaction_args)that);
      return false;
    }

    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();
      if (this_present_login || that_present_login) {
        if (!(this_present_login && that_present_login))
          return false;
        if (!this.login.equals(that.login))
          return false;
      }

      boolean this_present_tableName = true && this.isSetTableName();
      boolean that_present_tableName = true && that.isSetTableName();
      if (this_present_tableName || that_present_tableName) {
        if (!(this_present_tableName && that_present_tableName))
          return false;
        if (!this.tableName.equals(that.tableName))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
      if (isSetLogin())
        hashCode = hashCode * 8191 + login.hashCode();

      hashCode = hashCode * 8191 + ((isSetTableName()) ? 131071 : 524287);
      if (isSetTableName())
        hashCode = hashCode * 8191 + tableName.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(cancelCompaction_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLogin()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetTableName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.tableName, other.tableName);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("cancelCompaction_args(");
      boolean first = true;

      sb.append("login:");
      if (this.login == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.login, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("tableName:");
      if (this.tableName == null) {
        sb.append("null");
      } else {
        sb.append(this.tableName);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class cancelCompaction_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public cancelCompaction_argsStandardScheme getScheme() {
        return new cancelCompaction_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // LOGIN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.login = iprot.readBinary();
                struct.setLoginIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // TABLE_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.tableName = iprot.readString();
                struct.setTableNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, cancelCompaction_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.login != null) {
          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
          oprot.writeBinary(struct.login);
          oprot.writeFieldEnd();
        }
        if (struct.tableName != null) {
          oprot.writeFieldBegin(TABLE_NAME_FIELD_DESC);
          oprot.writeString(struct.tableName);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    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 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 {
        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);
        }
        if (struct.isSetTableName()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetLogin()) {
          oprot.writeBinary(struct.login);
        }
        if (struct.isSetTableName()) {
          oprot.writeString(struct.tableName);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, cancelCompaction_args struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.tableName = iprot.readString();
          struct.setTableNameIsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("cancelCompaction_result");

    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField OUCH3_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch3", org.apache.thrift.protocol.TType.STRUCT, (short)3);

    private static final org.apache.thrift.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
    public AccumuloException ouch3; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      OUCH1((short)1, "ouch1"),
      OUCH2((short)2, "ouch2"),
      OUCH3((short)3, "ouch3");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // OUCH1
            return OUCH1;
          case 2: // OUCH2
            return OUCH2;
          case 3: // OUCH3
            return OUCH3;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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.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.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);
    }

    public cancelCompaction_result() {
    }

    public cancelCompaction_result(
      AccumuloSecurityException ouch1,
      TableNotFoundException ouch2,
      AccumuloException ouch3)
    {
      this();
      this.ouch1 = ouch1;
      this.ouch2 = ouch2;
      this.ouch3 = ouch3;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public cancelCompaction_result(cancelCompaction_result other) {
      if (other.isSetOuch1()) {
        this.ouch1 = new AccumuloSecurityException(other.ouch1);
      }
      if (other.isSetOuch2()) {
        this.ouch2 = new TableNotFoundException(other.ouch2);
      }
      if (other.isSetOuch3()) {
        this.ouch3 = new AccumuloException(other.ouch3);
      }
    }

    public cancelCompaction_result deepCopy() {
      return new cancelCompaction_result(this);
    }

    @Override
    public void clear() {
      this.ouch1 = null;
      this.ouch2 = null;
      this.ouch3 = null;
    }

    public AccumuloSecurityException getOuch1() {
      return this.ouch1;
    }

    public cancelCompaction_result setOuch1(AccumuloSecurityException ouch1) {
      this.ouch1 = ouch1;
      return this;
    }

    public void unsetOuch1() {
      this.ouch1 = null;
    }

    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch1() {
      return this.ouch1 != null;
    }

    public void setOuch1IsSet(boolean value) {
      if (!value) {
        this.ouch1 = null;
      }
    }

    public TableNotFoundException getOuch2() {
      return this.ouch2;
    }

    public cancelCompaction_result setOuch2(TableNotFoundException ouch2) {
      this.ouch2 = ouch2;
      return this;
    }

    public void unsetOuch2() {
      this.ouch2 = null;
    }

    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch2() {
      return this.ouch2 != null;
    }

    public void setOuch2IsSet(boolean value) {
      if (!value) {
        this.ouch2 = null;
      }
    }

    public AccumuloException getOuch3() {
      return this.ouch3;
    }

    public cancelCompaction_result setOuch3(AccumuloException ouch3) {
      this.ouch3 = ouch3;
      return this;
    }

    public void unsetOuch3() {
      this.ouch3 = null;
    }

    /** Returns true if field ouch3 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch3() {
      return this.ouch3 != null;
    }

    public void setOuch3IsSet(boolean value) {
      if (!value) {
        this.ouch3 = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case OUCH1:
        if (value == null) {
          unsetOuch1();
        } else {
          setOuch1((AccumuloSecurityException)value);
        }
        break;

      case OUCH2:
        if (value == null) {
          unsetOuch2();
        } else {
          setOuch2((TableNotFoundException)value);
        }
        break;

      case OUCH3:
        if (value == null) {
          unsetOuch3();
        } else {
          setOuch3((AccumuloException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case OUCH1:
        return getOuch1();

      case OUCH2:
        return getOuch2();

      case OUCH3:
        return getOuch3();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case OUCH1:
        return isSetOuch1();
      case OUCH2:
        return isSetOuch2();
      case OUCH3:
        return isSetOuch3();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof cancelCompaction_result)
        return this.equals((cancelCompaction_result)that);
      return false;
    }

    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();
      if (this_present_ouch1 || that_present_ouch1) {
        if (!(this_present_ouch1 && that_present_ouch1))
          return false;
        if (!this.ouch1.equals(that.ouch1))
          return false;
      }

      boolean this_present_ouch2 = true && this.isSetOuch2();
      boolean that_present_ouch2 = true && that.isSetOuch2();
      if (this_present_ouch2 || that_present_ouch2) {
        if (!(this_present_ouch2 && that_present_ouch2))
          return false;
        if (!this.ouch2.equals(that.ouch2))
          return false;
      }

      boolean this_present_ouch3 = true && this.isSetOuch3();
      boolean that_present_ouch3 = true && that.isSetOuch3();
      if (this_present_ouch3 || that_present_ouch3) {
        if (!(this_present_ouch3 && that_present_ouch3))
          return false;
        if (!this.ouch3.equals(that.ouch3))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
      if (isSetOuch1())
        hashCode = hashCode * 8191 + ouch1.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
      if (isSetOuch2())
        hashCode = hashCode * 8191 + ouch2.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
      if (isSetOuch3())
        hashCode = hashCode * 8191 + ouch3.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(cancelCompaction_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch1()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch2()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch3()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch3, other.ouch3);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("cancelCompaction_result(");
      boolean first = true;

      sb.append("ouch1:");
      if (this.ouch1 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch1);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch2:");
      if (this.ouch2 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch2);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch3:");
      if (this.ouch3 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch3);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class cancelCompaction_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public cancelCompaction_resultStandardScheme getScheme() {
        return new cancelCompaction_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // OUCH1
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch1 = new AccumuloSecurityException();
                struct.ouch1.read(iprot);
                struct.setOuch1IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OUCH2
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch2 = new TableNotFoundException();
                struct.ouch2.read(iprot);
                struct.setOuch2IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // OUCH3
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch3 = new AccumuloException();
                struct.ouch3.read(iprot);
                struct.setOuch3IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, cancelCompaction_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.ouch1 != null) {
          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
          struct.ouch1.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch2 != null) {
          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
          struct.ouch2.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch3 != null) {
          oprot.writeFieldBegin(OUCH3_FIELD_DESC);
          struct.ouch3.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class cancelCompaction_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public cancelCompaction_resultTupleScheme getScheme() {
        return new cancelCompaction_resultTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetOuch2()) {
          optionals.set(1);
        }
        if (struct.isSetOuch3()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetOuch1()) {
          struct.ouch1.write(oprot);
        }
        if (struct.isSetOuch2()) {
          struct.ouch2.write(oprot);
        }
        if (struct.isSetOuch3()) {
          struct.ouch3.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, cancelCompaction_result struct) throws org.apache.thrift.TException {
        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);
          struct.setOuch1IsSet(true);
        }
        if (incoming.get(1)) {
          struct.ouch2 = new TableNotFoundException();
          struct.ouch2.read(iprot);
          struct.setOuch2IsSet(true);
        }
        if (incoming.get(2)) {
          struct.ouch3 = new AccumuloException();
          struct.ouch3.read(iprot);
          struct.setOuch3IsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("createTable_args");

    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField 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 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 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 java.nio.ByteBuffer login; // required
    public java.lang.String tableName; // required
    public boolean versioningIter; // required
    /**
     * 
     * @see TimeType
     */
    public TimeType type; // 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"),
      VERSIONING_ITER((short)3, "versioningIter"),
      /**
       * 
       * @see TimeType
       */
      TYPE((short)4, "type");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // LOGIN
            return LOGIN;
          case 2: // TABLE_NAME
            return TABLE_NAME;
          case 3: // VERSIONING_ITER
            return VERSIONING_ITER;
          case 4: // TYPE
            return TYPE;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __VERSIONINGITER_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.VERSIONING_ITER, new org.apache.thrift.meta_data.FieldMetaData("versioningIter", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          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 = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(createTable_args.class, metaDataMap);
    }

    public createTable_args() {
    }

    public createTable_args(
      java.nio.ByteBuffer login,
      java.lang.String tableName,
      boolean versioningIter,
      TimeType type)
    {
      this();
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      this.tableName = tableName;
      this.versioningIter = versioningIter;
      setVersioningIterIsSet(true);
      this.type = type;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public createTable_args(createTable_args other) {
      __isset_bitfield = other.__isset_bitfield;
      if (other.isSetLogin()) {
        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
      }
      if (other.isSetTableName()) {
        this.tableName = other.tableName;
      }
      this.versioningIter = other.versioningIter;
      if (other.isSetType()) {
        this.type = other.type;
      }
    }

    public createTable_args deepCopy() {
      return new createTable_args(this);
    }

    @Override
    public void clear() {
      this.login = null;
      this.tableName = null;
      setVersioningIterIsSet(false);
      this.versioningIter = false;
      this.type = null;
    }

    public byte[] getLogin() {
      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
      return login == null ? null : login.array();
    }

    public java.nio.ByteBuffer bufferForLogin() {
      return org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    public createTable_args setLogin(byte[] login) {
      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
      return this;
    }

    public createTable_args setLogin(java.nio.ByteBuffer login) {
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      return this;
    }

    public void unsetLogin() {
      this.login = null;
    }

    /** Returns true if field login is set (has been assigned a value) and false otherwise */
    public boolean isSetLogin() {
      return this.login != null;
    }

    public void setLoginIsSet(boolean value) {
      if (!value) {
        this.login = null;
      }
    }

    public java.lang.String getTableName() {
      return this.tableName;
    }

    public createTable_args setTableName(java.lang.String tableName) {
      this.tableName = tableName;
      return this;
    }

    public void unsetTableName() {
      this.tableName = null;
    }

    /** Returns true if field tableName is set (has been assigned a value) and false otherwise */
    public boolean isSetTableName() {
      return this.tableName != null;
    }

    public void setTableNameIsSet(boolean value) {
      if (!value) {
        this.tableName = null;
      }
    }

    public boolean isVersioningIter() {
      return this.versioningIter;
    }

    public createTable_args setVersioningIter(boolean versioningIter) {
      this.versioningIter = versioningIter;
      setVersioningIterIsSet(true);
      return this;
    }

    public void unsetVersioningIter() {
      __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 org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __VERSIONINGITER_ISSET_ID);
    }

    public void setVersioningIterIsSet(boolean value) {
      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __VERSIONINGITER_ISSET_ID, value);
    }

    /**
     * 
     * @see TimeType
     */
    public TimeType getType() {
      return this.type;
    }

    /**
     * 
     * @see TimeType
     */
    public createTable_args setType(TimeType type) {
      this.type = type;
      return this;
    }

    public void unsetType() {
      this.type = null;
    }

    /** Returns true if field type is set (has been assigned a value) and false otherwise */
    public boolean isSetType() {
      return this.type != null;
    }

    public void setTypeIsSet(boolean value) {
      if (!value) {
        this.type = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case LOGIN:
        if (value == null) {
          unsetLogin();
        } else {
          if (value instanceof byte[]) {
            setLogin((byte[])value);
          } else {
            setLogin((java.nio.ByteBuffer)value);
          }
        }
        break;

      case TABLE_NAME:
        if (value == null) {
          unsetTableName();
        } else {
          setTableName((java.lang.String)value);
        }
        break;

      case VERSIONING_ITER:
        if (value == null) {
          unsetVersioningIter();
        } else {
          setVersioningIter((java.lang.Boolean)value);
        }
        break;

      case TYPE:
        if (value == null) {
          unsetType();
        } else {
          setType((TimeType)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case LOGIN:
        return getLogin();

      case TABLE_NAME:
        return getTableName();

      case VERSIONING_ITER:
        return isVersioningIter();

      case TYPE:
        return getType();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case LOGIN:
        return isSetLogin();
      case TABLE_NAME:
        return isSetTableName();
      case VERSIONING_ITER:
        return isSetVersioningIter();
      case TYPE:
        return isSetType();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof createTable_args)
        return this.equals((createTable_args)that);
      return false;
    }

    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();
      if (this_present_login || that_present_login) {
        if (!(this_present_login && that_present_login))
          return false;
        if (!this.login.equals(that.login))
          return false;
      }

      boolean this_present_tableName = true && this.isSetTableName();
      boolean that_present_tableName = true && that.isSetTableName();
      if (this_present_tableName || that_present_tableName) {
        if (!(this_present_tableName && that_present_tableName))
          return false;
        if (!this.tableName.equals(that.tableName))
          return false;
      }

      boolean this_present_versioningIter = true;
      boolean that_present_versioningIter = true;
      if (this_present_versioningIter || that_present_versioningIter) {
        if (!(this_present_versioningIter && that_present_versioningIter))
          return false;
        if (this.versioningIter != that.versioningIter)
          return false;
      }

      boolean this_present_type = true && this.isSetType();
      boolean that_present_type = true && that.isSetType();
      if (this_present_type || that_present_type) {
        if (!(this_present_type && that_present_type))
          return false;
        if (!this.type.equals(that.type))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
      if (isSetLogin())
        hashCode = hashCode * 8191 + login.hashCode();

      hashCode = hashCode * 8191 + ((isSetTableName()) ? 131071 : 524287);
      if (isSetTableName())
        hashCode = hashCode * 8191 + tableName.hashCode();

      hashCode = hashCode * 8191 + ((versioningIter) ? 131071 : 524287);

      hashCode = hashCode * 8191 + ((isSetType()) ? 131071 : 524287);
      if (isSetType())
        hashCode = hashCode * 8191 + type.getValue();

      return hashCode;
    }

    @Override
    public int compareTo(createTable_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLogin()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetTableName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.tableName, other.tableName);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetVersioningIter()).compareTo(other.isSetVersioningIter());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetVersioningIter()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.versioningIter, other.versioningIter);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetType()).compareTo(other.isSetType());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetType()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.type, other.type);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("createTable_args(");
      boolean first = true;

      sb.append("login:");
      if (this.login == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.login, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("tableName:");
      if (this.tableName == null) {
        sb.append("null");
      } else {
        sb.append(this.tableName);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("versioningIter:");
      sb.append(this.versioningIter);
      first = false;
      if (!first) sb.append(", ");
      sb.append("type:");
      if (this.type == null) {
        sb.append("null");
      } else {
        sb.append(this.type);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, 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;
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class createTable_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public createTable_argsStandardScheme getScheme() {
        return new createTable_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // LOGIN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.login = iprot.readBinary();
                struct.setLoginIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // TABLE_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.tableName = iprot.readString();
                struct.setTableNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // VERSIONING_ITER
              if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
                struct.versioningIter = iprot.readBool();
                struct.setVersioningIterIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // TYPE
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.type = org.apache.accumulo.proxy.thrift.TimeType.findByValue(iprot.readI32());
                struct.setTypeIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, createTable_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.login != null) {
          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
          oprot.writeBinary(struct.login);
          oprot.writeFieldEnd();
        }
        if (struct.tableName != null) {
          oprot.writeFieldBegin(TABLE_NAME_FIELD_DESC);
          oprot.writeString(struct.tableName);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldBegin(VERSIONING_ITER_FIELD_DESC);
        oprot.writeBool(struct.versioningIter);
        oprot.writeFieldEnd();
        if (struct.type != null) {
          oprot.writeFieldBegin(TYPE_FIELD_DESC);
          oprot.writeI32(struct.type.getValue());
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    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 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 {
        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);
        }
        if (struct.isSetTableName()) {
          optionals.set(1);
        }
        if (struct.isSetVersioningIter()) {
          optionals.set(2);
        }
        if (struct.isSetType()) {
          optionals.set(3);
        }
        oprot.writeBitSet(optionals, 4);
        if (struct.isSetLogin()) {
          oprot.writeBinary(struct.login);
        }
        if (struct.isSetTableName()) {
          oprot.writeString(struct.tableName);
        }
        if (struct.isSetVersioningIter()) {
          oprot.writeBool(struct.versioningIter);
        }
        if (struct.isSetType()) {
          oprot.writeI32(struct.type.getValue());
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, createTable_args struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.tableName = iprot.readString();
          struct.setTableNameIsSet(true);
        }
        if (incoming.get(2)) {
          struct.versioningIter = iprot.readBool();
          struct.setVersioningIterIsSet(true);
        }
        if (incoming.get(3)) {
          struct.type = org.apache.accumulo.proxy.thrift.TimeType.findByValue(iprot.readI32());
          struct.setTypeIsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("createTable_result");

    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField OUCH3_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch3", org.apache.thrift.protocol.TType.STRUCT, (short)3);

    private static final org.apache.thrift.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
    public TableExistsException ouch3; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      OUCH1((short)1, "ouch1"),
      OUCH2((short)2, "ouch2"),
      OUCH3((short)3, "ouch3");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // OUCH1
            return OUCH1;
          case 2: // OUCH2
            return OUCH2;
          case 3: // OUCH3
            return OUCH3;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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.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.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);
    }

    public createTable_result() {
    }

    public createTable_result(
      AccumuloException ouch1,
      AccumuloSecurityException ouch2,
      TableExistsException ouch3)
    {
      this();
      this.ouch1 = ouch1;
      this.ouch2 = ouch2;
      this.ouch3 = ouch3;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public createTable_result(createTable_result other) {
      if (other.isSetOuch1()) {
        this.ouch1 = new AccumuloException(other.ouch1);
      }
      if (other.isSetOuch2()) {
        this.ouch2 = new AccumuloSecurityException(other.ouch2);
      }
      if (other.isSetOuch3()) {
        this.ouch3 = new TableExistsException(other.ouch3);
      }
    }

    public createTable_result deepCopy() {
      return new createTable_result(this);
    }

    @Override
    public void clear() {
      this.ouch1 = null;
      this.ouch2 = null;
      this.ouch3 = null;
    }

    public AccumuloException getOuch1() {
      return this.ouch1;
    }

    public createTable_result setOuch1(AccumuloException ouch1) {
      this.ouch1 = ouch1;
      return this;
    }

    public void unsetOuch1() {
      this.ouch1 = null;
    }

    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch1() {
      return this.ouch1 != null;
    }

    public void setOuch1IsSet(boolean value) {
      if (!value) {
        this.ouch1 = null;
      }
    }

    public AccumuloSecurityException getOuch2() {
      return this.ouch2;
    }

    public createTable_result setOuch2(AccumuloSecurityException ouch2) {
      this.ouch2 = ouch2;
      return this;
    }

    public void unsetOuch2() {
      this.ouch2 = null;
    }

    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch2() {
      return this.ouch2 != null;
    }

    public void setOuch2IsSet(boolean value) {
      if (!value) {
        this.ouch2 = null;
      }
    }

    public TableExistsException getOuch3() {
      return this.ouch3;
    }

    public createTable_result setOuch3(TableExistsException ouch3) {
      this.ouch3 = ouch3;
      return this;
    }

    public void unsetOuch3() {
      this.ouch3 = null;
    }

    /** Returns true if field ouch3 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch3() {
      return this.ouch3 != null;
    }

    public void setOuch3IsSet(boolean value) {
      if (!value) {
        this.ouch3 = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case OUCH1:
        if (value == null) {
          unsetOuch1();
        } else {
          setOuch1((AccumuloException)value);
        }
        break;

      case OUCH2:
        if (value == null) {
          unsetOuch2();
        } else {
          setOuch2((AccumuloSecurityException)value);
        }
        break;

      case OUCH3:
        if (value == null) {
          unsetOuch3();
        } else {
          setOuch3((TableExistsException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case OUCH1:
        return getOuch1();

      case OUCH2:
        return getOuch2();

      case OUCH3:
        return getOuch3();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case OUCH1:
        return isSetOuch1();
      case OUCH2:
        return isSetOuch2();
      case OUCH3:
        return isSetOuch3();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof createTable_result)
        return this.equals((createTable_result)that);
      return false;
    }

    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();
      if (this_present_ouch1 || that_present_ouch1) {
        if (!(this_present_ouch1 && that_present_ouch1))
          return false;
        if (!this.ouch1.equals(that.ouch1))
          return false;
      }

      boolean this_present_ouch2 = true && this.isSetOuch2();
      boolean that_present_ouch2 = true && that.isSetOuch2();
      if (this_present_ouch2 || that_present_ouch2) {
        if (!(this_present_ouch2 && that_present_ouch2))
          return false;
        if (!this.ouch2.equals(that.ouch2))
          return false;
      }

      boolean this_present_ouch3 = true && this.isSetOuch3();
      boolean that_present_ouch3 = true && that.isSetOuch3();
      if (this_present_ouch3 || that_present_ouch3) {
        if (!(this_present_ouch3 && that_present_ouch3))
          return false;
        if (!this.ouch3.equals(that.ouch3))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
      if (isSetOuch1())
        hashCode = hashCode * 8191 + ouch1.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
      if (isSetOuch2())
        hashCode = hashCode * 8191 + ouch2.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
      if (isSetOuch3())
        hashCode = hashCode * 8191 + ouch3.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(createTable_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch1()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch2()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch3()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch3, other.ouch3);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("createTable_result(");
      boolean first = true;

      sb.append("ouch1:");
      if (this.ouch1 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch1);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch2:");
      if (this.ouch2 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch2);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch3:");
      if (this.ouch3 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch3);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class createTable_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public createTable_resultStandardScheme getScheme() {
        return new createTable_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // OUCH1
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch1 = new AccumuloException();
                struct.ouch1.read(iprot);
                struct.setOuch1IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OUCH2
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch2 = new AccumuloSecurityException();
                struct.ouch2.read(iprot);
                struct.setOuch2IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // OUCH3
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch3 = new TableExistsException();
                struct.ouch3.read(iprot);
                struct.setOuch3IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, createTable_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.ouch1 != null) {
          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
          struct.ouch1.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch2 != null) {
          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
          struct.ouch2.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch3 != null) {
          oprot.writeFieldBegin(OUCH3_FIELD_DESC);
          struct.ouch3.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class createTable_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public createTable_resultTupleScheme getScheme() {
        return new createTable_resultTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetOuch2()) {
          optionals.set(1);
        }
        if (struct.isSetOuch3()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetOuch1()) {
          struct.ouch1.write(oprot);
        }
        if (struct.isSetOuch2()) {
          struct.ouch2.write(oprot);
        }
        if (struct.isSetOuch3()) {
          struct.ouch3.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, createTable_result struct) throws org.apache.thrift.TException {
        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);
          struct.setOuch1IsSet(true);
        }
        if (incoming.get(1)) {
          struct.ouch2 = new AccumuloSecurityException();
          struct.ouch2.read(iprot);
          struct.setOuch2IsSet(true);
        }
        if (incoming.get(2)) {
          struct.ouch3 = new TableExistsException();
          struct.ouch3.read(iprot);
          struct.setOuch3IsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("deleteTable_args");

    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField 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.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new deleteTable_argsStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new deleteTable_argsTupleSchemeFactory();

    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 java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // LOGIN
            return LOGIN;
          case 2: // TABLE_NAME
            return TABLE_NAME;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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 = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(deleteTable_args.class, metaDataMap);
    }

    public deleteTable_args() {
    }

    public deleteTable_args(
      java.nio.ByteBuffer login,
      java.lang.String tableName)
    {
      this();
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      this.tableName = tableName;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public deleteTable_args(deleteTable_args other) {
      if (other.isSetLogin()) {
        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
      }
      if (other.isSetTableName()) {
        this.tableName = other.tableName;
      }
    }

    public deleteTable_args deepCopy() {
      return new deleteTable_args(this);
    }

    @Override
    public void clear() {
      this.login = null;
      this.tableName = null;
    }

    public byte[] getLogin() {
      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
      return login == null ? null : login.array();
    }

    public java.nio.ByteBuffer bufferForLogin() {
      return org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    public deleteTable_args setLogin(byte[] login) {
      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
      return this;
    }

    public deleteTable_args setLogin(java.nio.ByteBuffer login) {
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      return this;
    }

    public void unsetLogin() {
      this.login = null;
    }

    /** Returns true if field login is set (has been assigned a value) and false otherwise */
    public boolean isSetLogin() {
      return this.login != null;
    }

    public void setLoginIsSet(boolean value) {
      if (!value) {
        this.login = null;
      }
    }

    public java.lang.String getTableName() {
      return this.tableName;
    }

    public deleteTable_args setTableName(java.lang.String tableName) {
      this.tableName = tableName;
      return this;
    }

    public void unsetTableName() {
      this.tableName = null;
    }

    /** Returns true if field tableName is set (has been assigned a value) and false otherwise */
    public boolean isSetTableName() {
      return this.tableName != null;
    }

    public void setTableNameIsSet(boolean value) {
      if (!value) {
        this.tableName = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case LOGIN:
        if (value == null) {
          unsetLogin();
        } else {
          if (value instanceof byte[]) {
            setLogin((byte[])value);
          } else {
            setLogin((java.nio.ByteBuffer)value);
          }
        }
        break;

      case TABLE_NAME:
        if (value == null) {
          unsetTableName();
        } else {
          setTableName((java.lang.String)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case LOGIN:
        return getLogin();

      case TABLE_NAME:
        return getTableName();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case LOGIN:
        return isSetLogin();
      case TABLE_NAME:
        return isSetTableName();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof deleteTable_args)
        return this.equals((deleteTable_args)that);
      return false;
    }

    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();
      if (this_present_login || that_present_login) {
        if (!(this_present_login && that_present_login))
          return false;
        if (!this.login.equals(that.login))
          return false;
      }

      boolean this_present_tableName = true && this.isSetTableName();
      boolean that_present_tableName = true && that.isSetTableName();
      if (this_present_tableName || that_present_tableName) {
        if (!(this_present_tableName && that_present_tableName))
          return false;
        if (!this.tableName.equals(that.tableName))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
      if (isSetLogin())
        hashCode = hashCode * 8191 + login.hashCode();

      hashCode = hashCode * 8191 + ((isSetTableName()) ? 131071 : 524287);
      if (isSetTableName())
        hashCode = hashCode * 8191 + tableName.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(deleteTable_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLogin()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetTableName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.tableName, other.tableName);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("deleteTable_args(");
      boolean first = true;

      sb.append("login:");
      if (this.login == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.login, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("tableName:");
      if (this.tableName == null) {
        sb.append("null");
      } else {
        sb.append(this.tableName);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class deleteTable_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public deleteTable_argsStandardScheme getScheme() {
        return new deleteTable_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // LOGIN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.login = iprot.readBinary();
                struct.setLoginIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // TABLE_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.tableName = iprot.readString();
                struct.setTableNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, deleteTable_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.login != null) {
          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
          oprot.writeBinary(struct.login);
          oprot.writeFieldEnd();
        }
        if (struct.tableName != null) {
          oprot.writeFieldBegin(TABLE_NAME_FIELD_DESC);
          oprot.writeString(struct.tableName);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    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 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 {
        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);
        }
        if (struct.isSetTableName()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetLogin()) {
          oprot.writeBinary(struct.login);
        }
        if (struct.isSetTableName()) {
          oprot.writeString(struct.tableName);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, deleteTable_args struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.tableName = iprot.readString();
          struct.setTableNameIsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("deleteTable_result");

    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField OUCH3_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch3", org.apache.thrift.protocol.TType.STRUCT, (short)3);

    private static final org.apache.thrift.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
    public TableNotFoundException ouch3; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      OUCH1((short)1, "ouch1"),
      OUCH2((short)2, "ouch2"),
      OUCH3((short)3, "ouch3");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // OUCH1
            return OUCH1;
          case 2: // OUCH2
            return OUCH2;
          case 3: // OUCH3
            return OUCH3;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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.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.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);
    }

    public deleteTable_result() {
    }

    public deleteTable_result(
      AccumuloException ouch1,
      AccumuloSecurityException ouch2,
      TableNotFoundException ouch3)
    {
      this();
      this.ouch1 = ouch1;
      this.ouch2 = ouch2;
      this.ouch3 = ouch3;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public deleteTable_result(deleteTable_result other) {
      if (other.isSetOuch1()) {
        this.ouch1 = new AccumuloException(other.ouch1);
      }
      if (other.isSetOuch2()) {
        this.ouch2 = new AccumuloSecurityException(other.ouch2);
      }
      if (other.isSetOuch3()) {
        this.ouch3 = new TableNotFoundException(other.ouch3);
      }
    }

    public deleteTable_result deepCopy() {
      return new deleteTable_result(this);
    }

    @Override
    public void clear() {
      this.ouch1 = null;
      this.ouch2 = null;
      this.ouch3 = null;
    }

    public AccumuloException getOuch1() {
      return this.ouch1;
    }

    public deleteTable_result setOuch1(AccumuloException ouch1) {
      this.ouch1 = ouch1;
      return this;
    }

    public void unsetOuch1() {
      this.ouch1 = null;
    }

    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch1() {
      return this.ouch1 != null;
    }

    public void setOuch1IsSet(boolean value) {
      if (!value) {
        this.ouch1 = null;
      }
    }

    public AccumuloSecurityException getOuch2() {
      return this.ouch2;
    }

    public deleteTable_result setOuch2(AccumuloSecurityException ouch2) {
      this.ouch2 = ouch2;
      return this;
    }

    public void unsetOuch2() {
      this.ouch2 = null;
    }

    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch2() {
      return this.ouch2 != null;
    }

    public void setOuch2IsSet(boolean value) {
      if (!value) {
        this.ouch2 = null;
      }
    }

    public TableNotFoundException getOuch3() {
      return this.ouch3;
    }

    public deleteTable_result setOuch3(TableNotFoundException ouch3) {
      this.ouch3 = ouch3;
      return this;
    }

    public void unsetOuch3() {
      this.ouch3 = null;
    }

    /** Returns true if field ouch3 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch3() {
      return this.ouch3 != null;
    }

    public void setOuch3IsSet(boolean value) {
      if (!value) {
        this.ouch3 = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case OUCH1:
        if (value == null) {
          unsetOuch1();
        } else {
          setOuch1((AccumuloException)value);
        }
        break;

      case OUCH2:
        if (value == null) {
          unsetOuch2();
        } else {
          setOuch2((AccumuloSecurityException)value);
        }
        break;

      case OUCH3:
        if (value == null) {
          unsetOuch3();
        } else {
          setOuch3((TableNotFoundException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case OUCH1:
        return getOuch1();

      case OUCH2:
        return getOuch2();

      case OUCH3:
        return getOuch3();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case OUCH1:
        return isSetOuch1();
      case OUCH2:
        return isSetOuch2();
      case OUCH3:
        return isSetOuch3();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof deleteTable_result)
        return this.equals((deleteTable_result)that);
      return false;
    }

    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();
      if (this_present_ouch1 || that_present_ouch1) {
        if (!(this_present_ouch1 && that_present_ouch1))
          return false;
        if (!this.ouch1.equals(that.ouch1))
          return false;
      }

      boolean this_present_ouch2 = true && this.isSetOuch2();
      boolean that_present_ouch2 = true && that.isSetOuch2();
      if (this_present_ouch2 || that_present_ouch2) {
        if (!(this_present_ouch2 && that_present_ouch2))
          return false;
        if (!this.ouch2.equals(that.ouch2))
          return false;
      }

      boolean this_present_ouch3 = true && this.isSetOuch3();
      boolean that_present_ouch3 = true && that.isSetOuch3();
      if (this_present_ouch3 || that_present_ouch3) {
        if (!(this_present_ouch3 && that_present_ouch3))
          return false;
        if (!this.ouch3.equals(that.ouch3))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
      if (isSetOuch1())
        hashCode = hashCode * 8191 + ouch1.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
      if (isSetOuch2())
        hashCode = hashCode * 8191 + ouch2.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
      if (isSetOuch3())
        hashCode = hashCode * 8191 + ouch3.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(deleteTable_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch1()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch2()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch3()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch3, other.ouch3);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("deleteTable_result(");
      boolean first = true;

      sb.append("ouch1:");
      if (this.ouch1 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch1);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch2:");
      if (this.ouch2 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch2);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch3:");
      if (this.ouch3 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch3);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class deleteTable_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public deleteTable_resultStandardScheme getScheme() {
        return new deleteTable_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // OUCH1
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch1 = new AccumuloException();
                struct.ouch1.read(iprot);
                struct.setOuch1IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OUCH2
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch2 = new AccumuloSecurityException();
                struct.ouch2.read(iprot);
                struct.setOuch2IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // OUCH3
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch3 = new TableNotFoundException();
                struct.ouch3.read(iprot);
                struct.setOuch3IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, deleteTable_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.ouch1 != null) {
          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
          struct.ouch1.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch2 != null) {
          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
          struct.ouch2.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch3 != null) {
          oprot.writeFieldBegin(OUCH3_FIELD_DESC);
          struct.ouch3.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class deleteTable_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public deleteTable_resultTupleScheme getScheme() {
        return new deleteTable_resultTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetOuch2()) {
          optionals.set(1);
        }
        if (struct.isSetOuch3()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetOuch1()) {
          struct.ouch1.write(oprot);
        }
        if (struct.isSetOuch2()) {
          struct.ouch2.write(oprot);
        }
        if (struct.isSetOuch3()) {
          struct.ouch3.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, deleteTable_result struct) throws org.apache.thrift.TException {
        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);
          struct.setOuch1IsSet(true);
        }
        if (incoming.get(1)) {
          struct.ouch2 = new AccumuloSecurityException();
          struct.ouch2.read(iprot);
          struct.setOuch2IsSet(true);
        }
        if (incoming.get(2)) {
          struct.ouch3 = new TableNotFoundException();
          struct.ouch3.read(iprot);
          struct.setOuch3IsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("deleteRows_args");

    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField 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 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 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 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 {
      LOGIN((short)1, "login"),
      TABLE_NAME((short)2, "tableName"),
      START_ROW((short)3, "startRow"),
      END_ROW((short)4, "endRow");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // LOGIN
            return LOGIN;
          case 2: // TABLE_NAME
            return TABLE_NAME;
          case 3: // START_ROW
            return START_ROW;
          case 4: // END_ROW
            return END_ROW;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.START_ROW, new org.apache.thrift.meta_data.FieldMetaData("startRow", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          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 = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(deleteRows_args.class, metaDataMap);
    }

    public deleteRows_args() {
    }

    public deleteRows_args(
      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);
      this.tableName = tableName;
      this.startRow = org.apache.thrift.TBaseHelper.copyBinary(startRow);
      this.endRow = org.apache.thrift.TBaseHelper.copyBinary(endRow);
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public deleteRows_args(deleteRows_args other) {
      if (other.isSetLogin()) {
        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
      }
      if (other.isSetTableName()) {
        this.tableName = other.tableName;
      }
      if (other.isSetStartRow()) {
        this.startRow = org.apache.thrift.TBaseHelper.copyBinary(other.startRow);
      }
      if (other.isSetEndRow()) {
        this.endRow = org.apache.thrift.TBaseHelper.copyBinary(other.endRow);
      }
    }

    public deleteRows_args deepCopy() {
      return new deleteRows_args(this);
    }

    @Override
    public void clear() {
      this.login = null;
      this.tableName = null;
      this.startRow = null;
      this.endRow = null;
    }

    public byte[] getLogin() {
      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
      return login == null ? null : login.array();
    }

    public java.nio.ByteBuffer bufferForLogin() {
      return org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    public deleteRows_args setLogin(byte[] login) {
      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
      return this;
    }

    public deleteRows_args setLogin(java.nio.ByteBuffer login) {
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      return this;
    }

    public void unsetLogin() {
      this.login = null;
    }

    /** Returns true if field login is set (has been assigned a value) and false otherwise */
    public boolean isSetLogin() {
      return this.login != null;
    }

    public void setLoginIsSet(boolean value) {
      if (!value) {
        this.login = null;
      }
    }

    public java.lang.String getTableName() {
      return this.tableName;
    }

    public deleteRows_args setTableName(java.lang.String tableName) {
      this.tableName = tableName;
      return this;
    }

    public void unsetTableName() {
      this.tableName = null;
    }

    /** Returns true if field tableName is set (has been assigned a value) and false otherwise */
    public boolean isSetTableName() {
      return this.tableName != null;
    }

    public void setTableNameIsSet(boolean value) {
      if (!value) {
        this.tableName = null;
      }
    }

    public byte[] getStartRow() {
      setStartRow(org.apache.thrift.TBaseHelper.rightSize(startRow));
      return startRow == null ? null : startRow.array();
    }

    public java.nio.ByteBuffer bufferForStartRow() {
      return org.apache.thrift.TBaseHelper.copyBinary(startRow);
    }

    public deleteRows_args setStartRow(byte[] startRow) {
      this.startRow = startRow == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(startRow.clone());
      return this;
    }

    public deleteRows_args setStartRow(java.nio.ByteBuffer startRow) {
      this.startRow = org.apache.thrift.TBaseHelper.copyBinary(startRow);
      return this;
    }

    public void unsetStartRow() {
      this.startRow = null;
    }

    /** Returns true if field startRow is set (has been assigned a value) and false otherwise */
    public boolean isSetStartRow() {
      return this.startRow != null;
    }

    public void setStartRowIsSet(boolean value) {
      if (!value) {
        this.startRow = null;
      }
    }

    public byte[] getEndRow() {
      setEndRow(org.apache.thrift.TBaseHelper.rightSize(endRow));
      return endRow == null ? null : endRow.array();
    }

    public java.nio.ByteBuffer bufferForEndRow() {
      return org.apache.thrift.TBaseHelper.copyBinary(endRow);
    }

    public deleteRows_args setEndRow(byte[] endRow) {
      this.endRow = endRow == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(endRow.clone());
      return this;
    }

    public deleteRows_args setEndRow(java.nio.ByteBuffer endRow) {
      this.endRow = org.apache.thrift.TBaseHelper.copyBinary(endRow);
      return this;
    }

    public void unsetEndRow() {
      this.endRow = null;
    }

    /** Returns true if field endRow is set (has been assigned a value) and false otherwise */
    public boolean isSetEndRow() {
      return this.endRow != null;
    }

    public void setEndRowIsSet(boolean value) {
      if (!value) {
        this.endRow = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case LOGIN:
        if (value == null) {
          unsetLogin();
        } else {
          if (value instanceof byte[]) {
            setLogin((byte[])value);
          } else {
            setLogin((java.nio.ByteBuffer)value);
          }
        }
        break;

      case TABLE_NAME:
        if (value == null) {
          unsetTableName();
        } else {
          setTableName((java.lang.String)value);
        }
        break;

      case START_ROW:
        if (value == null) {
          unsetStartRow();
        } else {
          if (value instanceof byte[]) {
            setStartRow((byte[])value);
          } else {
            setStartRow((java.nio.ByteBuffer)value);
          }
        }
        break;

      case END_ROW:
        if (value == null) {
          unsetEndRow();
        } else {
          if (value instanceof byte[]) {
            setEndRow((byte[])value);
          } else {
            setEndRow((java.nio.ByteBuffer)value);
          }
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case LOGIN:
        return getLogin();

      case TABLE_NAME:
        return getTableName();

      case START_ROW:
        return getStartRow();

      case END_ROW:
        return getEndRow();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case LOGIN:
        return isSetLogin();
      case TABLE_NAME:
        return isSetTableName();
      case START_ROW:
        return isSetStartRow();
      case END_ROW:
        return isSetEndRow();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof deleteRows_args)
        return this.equals((deleteRows_args)that);
      return false;
    }

    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();
      if (this_present_login || that_present_login) {
        if (!(this_present_login && that_present_login))
          return false;
        if (!this.login.equals(that.login))
          return false;
      }

      boolean this_present_tableName = true && this.isSetTableName();
      boolean that_present_tableName = true && that.isSetTableName();
      if (this_present_tableName || that_present_tableName) {
        if (!(this_present_tableName && that_present_tableName))
          return false;
        if (!this.tableName.equals(that.tableName))
          return false;
      }

      boolean this_present_startRow = true && this.isSetStartRow();
      boolean that_present_startRow = true && that.isSetStartRow();
      if (this_present_startRow || that_present_startRow) {
        if (!(this_present_startRow && that_present_startRow))
          return false;
        if (!this.startRow.equals(that.startRow))
          return false;
      }

      boolean this_present_endRow = true && this.isSetEndRow();
      boolean that_present_endRow = true && that.isSetEndRow();
      if (this_present_endRow || that_present_endRow) {
        if (!(this_present_endRow && that_present_endRow))
          return false;
        if (!this.endRow.equals(that.endRow))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
      if (isSetLogin())
        hashCode = hashCode * 8191 + login.hashCode();

      hashCode = hashCode * 8191 + ((isSetTableName()) ? 131071 : 524287);
      if (isSetTableName())
        hashCode = hashCode * 8191 + tableName.hashCode();

      hashCode = hashCode * 8191 + ((isSetStartRow()) ? 131071 : 524287);
      if (isSetStartRow())
        hashCode = hashCode * 8191 + startRow.hashCode();

      hashCode = hashCode * 8191 + ((isSetEndRow()) ? 131071 : 524287);
      if (isSetEndRow())
        hashCode = hashCode * 8191 + endRow.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(deleteRows_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLogin()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetTableName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.tableName, other.tableName);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetStartRow()).compareTo(other.isSetStartRow());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetStartRow()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.startRow, other.startRow);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetEndRow()).compareTo(other.isSetEndRow());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetEndRow()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.endRow, other.endRow);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("deleteRows_args(");
      boolean first = true;

      sb.append("login:");
      if (this.login == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.login, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("tableName:");
      if (this.tableName == null) {
        sb.append("null");
      } else {
        sb.append(this.tableName);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("startRow:");
      if (this.startRow == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.startRow, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("endRow:");
      if (this.endRow == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.endRow, sb);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class deleteRows_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public deleteRows_argsStandardScheme getScheme() {
        return new deleteRows_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // LOGIN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.login = iprot.readBinary();
                struct.setLoginIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // TABLE_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.tableName = iprot.readString();
                struct.setTableNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // START_ROW
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.startRow = iprot.readBinary();
                struct.setStartRowIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // END_ROW
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.endRow = iprot.readBinary();
                struct.setEndRowIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, deleteRows_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.login != null) {
          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
          oprot.writeBinary(struct.login);
          oprot.writeFieldEnd();
        }
        if (struct.tableName != null) {
          oprot.writeFieldBegin(TABLE_NAME_FIELD_DESC);
          oprot.writeString(struct.tableName);
          oprot.writeFieldEnd();
        }
        if (struct.startRow != null) {
          oprot.writeFieldBegin(START_ROW_FIELD_DESC);
          oprot.writeBinary(struct.startRow);
          oprot.writeFieldEnd();
        }
        if (struct.endRow != null) {
          oprot.writeFieldBegin(END_ROW_FIELD_DESC);
          oprot.writeBinary(struct.endRow);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    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 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 {
        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);
        }
        if (struct.isSetTableName()) {
          optionals.set(1);
        }
        if (struct.isSetStartRow()) {
          optionals.set(2);
        }
        if (struct.isSetEndRow()) {
          optionals.set(3);
        }
        oprot.writeBitSet(optionals, 4);
        if (struct.isSetLogin()) {
          oprot.writeBinary(struct.login);
        }
        if (struct.isSetTableName()) {
          oprot.writeString(struct.tableName);
        }
        if (struct.isSetStartRow()) {
          oprot.writeBinary(struct.startRow);
        }
        if (struct.isSetEndRow()) {
          oprot.writeBinary(struct.endRow);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, deleteRows_args struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.tableName = iprot.readString();
          struct.setTableNameIsSet(true);
        }
        if (incoming.get(2)) {
          struct.startRow = iprot.readBinary();
          struct.setStartRowIsSet(true);
        }
        if (incoming.get(3)) {
          struct.endRow = iprot.readBinary();
          struct.setEndRowIsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("deleteRows_result");

    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField OUCH3_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch3", org.apache.thrift.protocol.TType.STRUCT, (short)3);

    private static final org.apache.thrift.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
    public TableNotFoundException ouch3; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      OUCH1((short)1, "ouch1"),
      OUCH2((short)2, "ouch2"),
      OUCH3((short)3, "ouch3");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // OUCH1
            return OUCH1;
          case 2: // OUCH2
            return OUCH2;
          case 3: // OUCH3
            return OUCH3;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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.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.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);
    }

    public deleteRows_result() {
    }

    public deleteRows_result(
      AccumuloException ouch1,
      AccumuloSecurityException ouch2,
      TableNotFoundException ouch3)
    {
      this();
      this.ouch1 = ouch1;
      this.ouch2 = ouch2;
      this.ouch3 = ouch3;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public deleteRows_result(deleteRows_result other) {
      if (other.isSetOuch1()) {
        this.ouch1 = new AccumuloException(other.ouch1);
      }
      if (other.isSetOuch2()) {
        this.ouch2 = new AccumuloSecurityException(other.ouch2);
      }
      if (other.isSetOuch3()) {
        this.ouch3 = new TableNotFoundException(other.ouch3);
      }
    }

    public deleteRows_result deepCopy() {
      return new deleteRows_result(this);
    }

    @Override
    public void clear() {
      this.ouch1 = null;
      this.ouch2 = null;
      this.ouch3 = null;
    }

    public AccumuloException getOuch1() {
      return this.ouch1;
    }

    public deleteRows_result setOuch1(AccumuloException ouch1) {
      this.ouch1 = ouch1;
      return this;
    }

    public void unsetOuch1() {
      this.ouch1 = null;
    }

    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch1() {
      return this.ouch1 != null;
    }

    public void setOuch1IsSet(boolean value) {
      if (!value) {
        this.ouch1 = null;
      }
    }

    public AccumuloSecurityException getOuch2() {
      return this.ouch2;
    }

    public deleteRows_result setOuch2(AccumuloSecurityException ouch2) {
      this.ouch2 = ouch2;
      return this;
    }

    public void unsetOuch2() {
      this.ouch2 = null;
    }

    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch2() {
      return this.ouch2 != null;
    }

    public void setOuch2IsSet(boolean value) {
      if (!value) {
        this.ouch2 = null;
      }
    }

    public TableNotFoundException getOuch3() {
      return this.ouch3;
    }

    public deleteRows_result setOuch3(TableNotFoundException ouch3) {
      this.ouch3 = ouch3;
      return this;
    }

    public void unsetOuch3() {
      this.ouch3 = null;
    }

    /** Returns true if field ouch3 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch3() {
      return this.ouch3 != null;
    }

    public void setOuch3IsSet(boolean value) {
      if (!value) {
        this.ouch3 = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case OUCH1:
        if (value == null) {
          unsetOuch1();
        } else {
          setOuch1((AccumuloException)value);
        }
        break;

      case OUCH2:
        if (value == null) {
          unsetOuch2();
        } else {
          setOuch2((AccumuloSecurityException)value);
        }
        break;

      case OUCH3:
        if (value == null) {
          unsetOuch3();
        } else {
          setOuch3((TableNotFoundException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case OUCH1:
        return getOuch1();

      case OUCH2:
        return getOuch2();

      case OUCH3:
        return getOuch3();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case OUCH1:
        return isSetOuch1();
      case OUCH2:
        return isSetOuch2();
      case OUCH3:
        return isSetOuch3();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof deleteRows_result)
        return this.equals((deleteRows_result)that);
      return false;
    }

    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();
      if (this_present_ouch1 || that_present_ouch1) {
        if (!(this_present_ouch1 && that_present_ouch1))
          return false;
        if (!this.ouch1.equals(that.ouch1))
          return false;
      }

      boolean this_present_ouch2 = true && this.isSetOuch2();
      boolean that_present_ouch2 = true && that.isSetOuch2();
      if (this_present_ouch2 || that_present_ouch2) {
        if (!(this_present_ouch2 && that_present_ouch2))
          return false;
        if (!this.ouch2.equals(that.ouch2))
          return false;
      }

      boolean this_present_ouch3 = true && this.isSetOuch3();
      boolean that_present_ouch3 = true && that.isSetOuch3();
      if (this_present_ouch3 || that_present_ouch3) {
        if (!(this_present_ouch3 && that_present_ouch3))
          return false;
        if (!this.ouch3.equals(that.ouch3))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
      if (isSetOuch1())
        hashCode = hashCode * 8191 + ouch1.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
      if (isSetOuch2())
        hashCode = hashCode * 8191 + ouch2.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
      if (isSetOuch3())
        hashCode = hashCode * 8191 + ouch3.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(deleteRows_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch1()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch2()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch3()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch3, other.ouch3);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("deleteRows_result(");
      boolean first = true;

      sb.append("ouch1:");
      if (this.ouch1 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch1);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch2:");
      if (this.ouch2 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch2);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch3:");
      if (this.ouch3 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch3);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class deleteRows_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public deleteRows_resultStandardScheme getScheme() {
        return new deleteRows_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // OUCH1
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch1 = new AccumuloException();
                struct.ouch1.read(iprot);
                struct.setOuch1IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OUCH2
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch2 = new AccumuloSecurityException();
                struct.ouch2.read(iprot);
                struct.setOuch2IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // OUCH3
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch3 = new TableNotFoundException();
                struct.ouch3.read(iprot);
                struct.setOuch3IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, deleteRows_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.ouch1 != null) {
          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
          struct.ouch1.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch2 != null) {
          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
          struct.ouch2.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch3 != null) {
          oprot.writeFieldBegin(OUCH3_FIELD_DESC);
          struct.ouch3.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class deleteRows_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public deleteRows_resultTupleScheme getScheme() {
        return new deleteRows_resultTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetOuch2()) {
          optionals.set(1);
        }
        if (struct.isSetOuch3()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetOuch1()) {
          struct.ouch1.write(oprot);
        }
        if (struct.isSetOuch2()) {
          struct.ouch2.write(oprot);
        }
        if (struct.isSetOuch3()) {
          struct.ouch3.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, deleteRows_result struct) throws org.apache.thrift.TException {
        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);
          struct.setOuch1IsSet(true);
        }
        if (incoming.get(1)) {
          struct.ouch2 = new AccumuloSecurityException();
          struct.ouch2.read(iprot);
          struct.setOuch2IsSet(true);
        }
        if (incoming.get(2)) {
          struct.ouch3 = new TableNotFoundException();
          struct.ouch3.read(iprot);
          struct.setOuch3IsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("exportTable_args");

    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField 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 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 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 {
      LOGIN((short)1, "login"),
      TABLE_NAME((short)2, "tableName"),
      EXPORT_DIR((short)3, "exportDir");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // LOGIN
            return LOGIN;
          case 2: // TABLE_NAME
            return TABLE_NAME;
          case 3: // EXPORT_DIR
            return EXPORT_DIR;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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 = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(exportTable_args.class, metaDataMap);
    }

    public exportTable_args() {
    }

    public exportTable_args(
      java.nio.ByteBuffer login,
      java.lang.String tableName,
      java.lang.String exportDir)
    {
      this();
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      this.tableName = tableName;
      this.exportDir = exportDir;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public exportTable_args(exportTable_args other) {
      if (other.isSetLogin()) {
        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
      }
      if (other.isSetTableName()) {
        this.tableName = other.tableName;
      }
      if (other.isSetExportDir()) {
        this.exportDir = other.exportDir;
      }
    }

    public exportTable_args deepCopy() {
      return new exportTable_args(this);
    }

    @Override
    public void clear() {
      this.login = null;
      this.tableName = null;
      this.exportDir = null;
    }

    public byte[] getLogin() {
      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
      return login == null ? null : login.array();
    }

    public java.nio.ByteBuffer bufferForLogin() {
      return org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    public exportTable_args setLogin(byte[] login) {
      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
      return this;
    }

    public exportTable_args setLogin(java.nio.ByteBuffer login) {
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      return this;
    }

    public void unsetLogin() {
      this.login = null;
    }

    /** Returns true if field login is set (has been assigned a value) and false otherwise */
    public boolean isSetLogin() {
      return this.login != null;
    }

    public void setLoginIsSet(boolean value) {
      if (!value) {
        this.login = null;
      }
    }

    public java.lang.String getTableName() {
      return this.tableName;
    }

    public exportTable_args setTableName(java.lang.String tableName) {
      this.tableName = tableName;
      return this;
    }

    public void unsetTableName() {
      this.tableName = null;
    }

    /** Returns true if field tableName is set (has been assigned a value) and false otherwise */
    public boolean isSetTableName() {
      return this.tableName != null;
    }

    public void setTableNameIsSet(boolean value) {
      if (!value) {
        this.tableName = null;
      }
    }

    public java.lang.String getExportDir() {
      return this.exportDir;
    }

    public exportTable_args setExportDir(java.lang.String exportDir) {
      this.exportDir = exportDir;
      return this;
    }

    public void unsetExportDir() {
      this.exportDir = null;
    }

    /** Returns true if field exportDir is set (has been assigned a value) and false otherwise */
    public boolean isSetExportDir() {
      return this.exportDir != null;
    }

    public void setExportDirIsSet(boolean value) {
      if (!value) {
        this.exportDir = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case LOGIN:
        if (value == null) {
          unsetLogin();
        } else {
          if (value instanceof byte[]) {
            setLogin((byte[])value);
          } else {
            setLogin((java.nio.ByteBuffer)value);
          }
        }
        break;

      case TABLE_NAME:
        if (value == null) {
          unsetTableName();
        } else {
          setTableName((java.lang.String)value);
        }
        break;

      case EXPORT_DIR:
        if (value == null) {
          unsetExportDir();
        } else {
          setExportDir((java.lang.String)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case LOGIN:
        return getLogin();

      case TABLE_NAME:
        return getTableName();

      case EXPORT_DIR:
        return getExportDir();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case LOGIN:
        return isSetLogin();
      case TABLE_NAME:
        return isSetTableName();
      case EXPORT_DIR:
        return isSetExportDir();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof exportTable_args)
        return this.equals((exportTable_args)that);
      return false;
    }

    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();
      if (this_present_login || that_present_login) {
        if (!(this_present_login && that_present_login))
          return false;
        if (!this.login.equals(that.login))
          return false;
      }

      boolean this_present_tableName = true && this.isSetTableName();
      boolean that_present_tableName = true && that.isSetTableName();
      if (this_present_tableName || that_present_tableName) {
        if (!(this_present_tableName && that_present_tableName))
          return false;
        if (!this.tableName.equals(that.tableName))
          return false;
      }

      boolean this_present_exportDir = true && this.isSetExportDir();
      boolean that_present_exportDir = true && that.isSetExportDir();
      if (this_present_exportDir || that_present_exportDir) {
        if (!(this_present_exportDir && that_present_exportDir))
          return false;
        if (!this.exportDir.equals(that.exportDir))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
      if (isSetLogin())
        hashCode = hashCode * 8191 + login.hashCode();

      hashCode = hashCode * 8191 + ((isSetTableName()) ? 131071 : 524287);
      if (isSetTableName())
        hashCode = hashCode * 8191 + tableName.hashCode();

      hashCode = hashCode * 8191 + ((isSetExportDir()) ? 131071 : 524287);
      if (isSetExportDir())
        hashCode = hashCode * 8191 + exportDir.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(exportTable_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLogin()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetTableName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.tableName, other.tableName);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetExportDir()).compareTo(other.isSetExportDir());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetExportDir()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.exportDir, other.exportDir);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("exportTable_args(");
      boolean first = true;

      sb.append("login:");
      if (this.login == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.login, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("tableName:");
      if (this.tableName == null) {
        sb.append("null");
      } else {
        sb.append(this.tableName);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("exportDir:");
      if (this.exportDir == null) {
        sb.append("null");
      } else {
        sb.append(this.exportDir);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class exportTable_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public exportTable_argsStandardScheme getScheme() {
        return new exportTable_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // LOGIN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.login = iprot.readBinary();
                struct.setLoginIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // TABLE_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.tableName = iprot.readString();
                struct.setTableNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // EXPORT_DIR
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.exportDir = iprot.readString();
                struct.setExportDirIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, exportTable_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.login != null) {
          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
          oprot.writeBinary(struct.login);
          oprot.writeFieldEnd();
        }
        if (struct.tableName != null) {
          oprot.writeFieldBegin(TABLE_NAME_FIELD_DESC);
          oprot.writeString(struct.tableName);
          oprot.writeFieldEnd();
        }
        if (struct.exportDir != null) {
          oprot.writeFieldBegin(EXPORT_DIR_FIELD_DESC);
          oprot.writeString(struct.exportDir);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    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 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 {
        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);
        }
        if (struct.isSetTableName()) {
          optionals.set(1);
        }
        if (struct.isSetExportDir()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetLogin()) {
          oprot.writeBinary(struct.login);
        }
        if (struct.isSetTableName()) {
          oprot.writeString(struct.tableName);
        }
        if (struct.isSetExportDir()) {
          oprot.writeString(struct.exportDir);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, exportTable_args struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.tableName = iprot.readString();
          struct.setTableNameIsSet(true);
        }
        if (incoming.get(2)) {
          struct.exportDir = iprot.readString();
          struct.setExportDirIsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("exportTable_result");

    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField OUCH3_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch3", org.apache.thrift.protocol.TType.STRUCT, (short)3);

    private static final org.apache.thrift.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
    public TableNotFoundException ouch3; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      OUCH1((short)1, "ouch1"),
      OUCH2((short)2, "ouch2"),
      OUCH3((short)3, "ouch3");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // OUCH1
            return OUCH1;
          case 2: // OUCH2
            return OUCH2;
          case 3: // OUCH3
            return OUCH3;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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.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.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);
    }

    public exportTable_result() {
    }

    public exportTable_result(
      AccumuloException ouch1,
      AccumuloSecurityException ouch2,
      TableNotFoundException ouch3)
    {
      this();
      this.ouch1 = ouch1;
      this.ouch2 = ouch2;
      this.ouch3 = ouch3;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public exportTable_result(exportTable_result other) {
      if (other.isSetOuch1()) {
        this.ouch1 = new AccumuloException(other.ouch1);
      }
      if (other.isSetOuch2()) {
        this.ouch2 = new AccumuloSecurityException(other.ouch2);
      }
      if (other.isSetOuch3()) {
        this.ouch3 = new TableNotFoundException(other.ouch3);
      }
    }

    public exportTable_result deepCopy() {
      return new exportTable_result(this);
    }

    @Override
    public void clear() {
      this.ouch1 = null;
      this.ouch2 = null;
      this.ouch3 = null;
    }

    public AccumuloException getOuch1() {
      return this.ouch1;
    }

    public exportTable_result setOuch1(AccumuloException ouch1) {
      this.ouch1 = ouch1;
      return this;
    }

    public void unsetOuch1() {
      this.ouch1 = null;
    }

    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch1() {
      return this.ouch1 != null;
    }

    public void setOuch1IsSet(boolean value) {
      if (!value) {
        this.ouch1 = null;
      }
    }

    public AccumuloSecurityException getOuch2() {
      return this.ouch2;
    }

    public exportTable_result setOuch2(AccumuloSecurityException ouch2) {
      this.ouch2 = ouch2;
      return this;
    }

    public void unsetOuch2() {
      this.ouch2 = null;
    }

    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch2() {
      return this.ouch2 != null;
    }

    public void setOuch2IsSet(boolean value) {
      if (!value) {
        this.ouch2 = null;
      }
    }

    public TableNotFoundException getOuch3() {
      return this.ouch3;
    }

    public exportTable_result setOuch3(TableNotFoundException ouch3) {
      this.ouch3 = ouch3;
      return this;
    }

    public void unsetOuch3() {
      this.ouch3 = null;
    }

    /** Returns true if field ouch3 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch3() {
      return this.ouch3 != null;
    }

    public void setOuch3IsSet(boolean value) {
      if (!value) {
        this.ouch3 = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case OUCH1:
        if (value == null) {
          unsetOuch1();
        } else {
          setOuch1((AccumuloException)value);
        }
        break;

      case OUCH2:
        if (value == null) {
          unsetOuch2();
        } else {
          setOuch2((AccumuloSecurityException)value);
        }
        break;

      case OUCH3:
        if (value == null) {
          unsetOuch3();
        } else {
          setOuch3((TableNotFoundException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case OUCH1:
        return getOuch1();

      case OUCH2:
        return getOuch2();

      case OUCH3:
        return getOuch3();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case OUCH1:
        return isSetOuch1();
      case OUCH2:
        return isSetOuch2();
      case OUCH3:
        return isSetOuch3();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof exportTable_result)
        return this.equals((exportTable_result)that);
      return false;
    }

    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();
      if (this_present_ouch1 || that_present_ouch1) {
        if (!(this_present_ouch1 && that_present_ouch1))
          return false;
        if (!this.ouch1.equals(that.ouch1))
          return false;
      }

      boolean this_present_ouch2 = true && this.isSetOuch2();
      boolean that_present_ouch2 = true && that.isSetOuch2();
      if (this_present_ouch2 || that_present_ouch2) {
        if (!(this_present_ouch2 && that_present_ouch2))
          return false;
        if (!this.ouch2.equals(that.ouch2))
          return false;
      }

      boolean this_present_ouch3 = true && this.isSetOuch3();
      boolean that_present_ouch3 = true && that.isSetOuch3();
      if (this_present_ouch3 || that_present_ouch3) {
        if (!(this_present_ouch3 && that_present_ouch3))
          return false;
        if (!this.ouch3.equals(that.ouch3))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
      if (isSetOuch1())
        hashCode = hashCode * 8191 + ouch1.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
      if (isSetOuch2())
        hashCode = hashCode * 8191 + ouch2.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
      if (isSetOuch3())
        hashCode = hashCode * 8191 + ouch3.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(exportTable_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch1()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch2()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch3()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch3, other.ouch3);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("exportTable_result(");
      boolean first = true;

      sb.append("ouch1:");
      if (this.ouch1 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch1);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch2:");
      if (this.ouch2 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch2);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch3:");
      if (this.ouch3 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch3);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class exportTable_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public exportTable_resultStandardScheme getScheme() {
        return new exportTable_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // OUCH1
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch1 = new AccumuloException();
                struct.ouch1.read(iprot);
                struct.setOuch1IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OUCH2
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch2 = new AccumuloSecurityException();
                struct.ouch2.read(iprot);
                struct.setOuch2IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // OUCH3
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch3 = new TableNotFoundException();
                struct.ouch3.read(iprot);
                struct.setOuch3IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, exportTable_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.ouch1 != null) {
          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
          struct.ouch1.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch2 != null) {
          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
          struct.ouch2.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch3 != null) {
          oprot.writeFieldBegin(OUCH3_FIELD_DESC);
          struct.ouch3.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class exportTable_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public exportTable_resultTupleScheme getScheme() {
        return new exportTable_resultTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetOuch2()) {
          optionals.set(1);
        }
        if (struct.isSetOuch3()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetOuch1()) {
          struct.ouch1.write(oprot);
        }
        if (struct.isSetOuch2()) {
          struct.ouch2.write(oprot);
        }
        if (struct.isSetOuch3()) {
          struct.ouch3.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, exportTable_result struct) throws org.apache.thrift.TException {
        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);
          struct.setOuch1IsSet(true);
        }
        if (incoming.get(1)) {
          struct.ouch2 = new AccumuloSecurityException();
          struct.ouch2.read(iprot);
          struct.setOuch2IsSet(true);
        }
        if (incoming.get(2)) {
          struct.ouch3 = new TableNotFoundException();
          struct.ouch3.read(iprot);
          struct.setOuch3IsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("flushTable_args");

    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField 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 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 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 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 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. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      LOGIN((short)1, "login"),
      TABLE_NAME((short)2, "tableName"),
      START_ROW((short)3, "startRow"),
      END_ROW((short)4, "endRow"),
      WAIT((short)5, "wait");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // LOGIN
            return LOGIN;
          case 2: // TABLE_NAME
            return TABLE_NAME;
          case 3: // START_ROW
            return START_ROW;
          case 4: // END_ROW
            return END_ROW;
          case 5: // WAIT
            return WAIT;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __WAIT_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.START_ROW, new org.apache.thrift.meta_data.FieldMetaData("startRow", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          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)));
      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 = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(flushTable_args.class, metaDataMap);
    }

    public flushTable_args() {
    }

    public flushTable_args(
      java.nio.ByteBuffer login,
      java.lang.String tableName,
      java.nio.ByteBuffer startRow,
      java.nio.ByteBuffer endRow,
      boolean wait)
    {
      this();
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      this.tableName = tableName;
      this.startRow = org.apache.thrift.TBaseHelper.copyBinary(startRow);
      this.endRow = org.apache.thrift.TBaseHelper.copyBinary(endRow);
      this.wait = wait;
      setWaitIsSet(true);
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public flushTable_args(flushTable_args other) {
      __isset_bitfield = other.__isset_bitfield;
      if (other.isSetLogin()) {
        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
      }
      if (other.isSetTableName()) {
        this.tableName = other.tableName;
      }
      if (other.isSetStartRow()) {
        this.startRow = org.apache.thrift.TBaseHelper.copyBinary(other.startRow);
      }
      if (other.isSetEndRow()) {
        this.endRow = org.apache.thrift.TBaseHelper.copyBinary(other.endRow);
      }
      this.wait = other.wait;
    }

    public flushTable_args deepCopy() {
      return new flushTable_args(this);
    }

    @Override
    public void clear() {
      this.login = null;
      this.tableName = null;
      this.startRow = null;
      this.endRow = null;
      setWaitIsSet(false);
      this.wait = false;
    }

    public byte[] getLogin() {
      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
      return login == null ? null : login.array();
    }

    public java.nio.ByteBuffer bufferForLogin() {
      return org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    public flushTable_args setLogin(byte[] login) {
      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
      return this;
    }

    public flushTable_args setLogin(java.nio.ByteBuffer login) {
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      return this;
    }

    public void unsetLogin() {
      this.login = null;
    }

    /** Returns true if field login is set (has been assigned a value) and false otherwise */
    public boolean isSetLogin() {
      return this.login != null;
    }

    public void setLoginIsSet(boolean value) {
      if (!value) {
        this.login = null;
      }
    }

    public java.lang.String getTableName() {
      return this.tableName;
    }

    public flushTable_args setTableName(java.lang.String tableName) {
      this.tableName = tableName;
      return this;
    }

    public void unsetTableName() {
      this.tableName = null;
    }

    /** Returns true if field tableName is set (has been assigned a value) and false otherwise */
    public boolean isSetTableName() {
      return this.tableName != null;
    }

    public void setTableNameIsSet(boolean value) {
      if (!value) {
        this.tableName = null;
      }
    }

    public byte[] getStartRow() {
      setStartRow(org.apache.thrift.TBaseHelper.rightSize(startRow));
      return startRow == null ? null : startRow.array();
    }

    public java.nio.ByteBuffer bufferForStartRow() {
      return org.apache.thrift.TBaseHelper.copyBinary(startRow);
    }

    public flushTable_args setStartRow(byte[] startRow) {
      this.startRow = startRow == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(startRow.clone());
      return this;
    }

    public flushTable_args setStartRow(java.nio.ByteBuffer startRow) {
      this.startRow = org.apache.thrift.TBaseHelper.copyBinary(startRow);
      return this;
    }

    public void unsetStartRow() {
      this.startRow = null;
    }

    /** Returns true if field startRow is set (has been assigned a value) and false otherwise */
    public boolean isSetStartRow() {
      return this.startRow != null;
    }

    public void setStartRowIsSet(boolean value) {
      if (!value) {
        this.startRow = null;
      }
    }

    public byte[] getEndRow() {
      setEndRow(org.apache.thrift.TBaseHelper.rightSize(endRow));
      return endRow == null ? null : endRow.array();
    }

    public java.nio.ByteBuffer bufferForEndRow() {
      return org.apache.thrift.TBaseHelper.copyBinary(endRow);
    }

    public flushTable_args setEndRow(byte[] endRow) {
      this.endRow = endRow == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(endRow.clone());
      return this;
    }

    public flushTable_args setEndRow(java.nio.ByteBuffer endRow) {
      this.endRow = org.apache.thrift.TBaseHelper.copyBinary(endRow);
      return this;
    }

    public void unsetEndRow() {
      this.endRow = null;
    }

    /** Returns true if field endRow is set (has been assigned a value) and false otherwise */
    public boolean isSetEndRow() {
      return this.endRow != null;
    }

    public void setEndRowIsSet(boolean value) {
      if (!value) {
        this.endRow = null;
      }
    }

    public boolean isWait() {
      return this.wait;
    }

    public flushTable_args setWait(boolean wait) {
      this.wait = wait;
      setWaitIsSet(true);
      return this;
    }

    public void unsetWait() {
      __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 org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __WAIT_ISSET_ID);
    }

    public void setWaitIsSet(boolean value) {
      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __WAIT_ISSET_ID, value);
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case LOGIN:
        if (value == null) {
          unsetLogin();
        } else {
          if (value instanceof byte[]) {
            setLogin((byte[])value);
          } else {
            setLogin((java.nio.ByteBuffer)value);
          }
        }
        break;

      case TABLE_NAME:
        if (value == null) {
          unsetTableName();
        } else {
          setTableName((java.lang.String)value);
        }
        break;

      case START_ROW:
        if (value == null) {
          unsetStartRow();
        } else {
          if (value instanceof byte[]) {
            setStartRow((byte[])value);
          } else {
            setStartRow((java.nio.ByteBuffer)value);
          }
        }
        break;

      case END_ROW:
        if (value == null) {
          unsetEndRow();
        } else {
          if (value instanceof byte[]) {
            setEndRow((byte[])value);
          } else {
            setEndRow((java.nio.ByteBuffer)value);
          }
        }
        break;

      case WAIT:
        if (value == null) {
          unsetWait();
        } else {
          setWait((java.lang.Boolean)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case LOGIN:
        return getLogin();

      case TABLE_NAME:
        return getTableName();

      case START_ROW:
        return getStartRow();

      case END_ROW:
        return getEndRow();

      case WAIT:
        return isWait();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case LOGIN:
        return isSetLogin();
      case TABLE_NAME:
        return isSetTableName();
      case START_ROW:
        return isSetStartRow();
      case END_ROW:
        return isSetEndRow();
      case WAIT:
        return isSetWait();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof flushTable_args)
        return this.equals((flushTable_args)that);
      return false;
    }

    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();
      if (this_present_login || that_present_login) {
        if (!(this_present_login && that_present_login))
          return false;
        if (!this.login.equals(that.login))
          return false;
      }

      boolean this_present_tableName = true && this.isSetTableName();
      boolean that_present_tableName = true && that.isSetTableName();
      if (this_present_tableName || that_present_tableName) {
        if (!(this_present_tableName && that_present_tableName))
          return false;
        if (!this.tableName.equals(that.tableName))
          return false;
      }

      boolean this_present_startRow = true && this.isSetStartRow();
      boolean that_present_startRow = true && that.isSetStartRow();
      if (this_present_startRow || that_present_startRow) {
        if (!(this_present_startRow && that_present_startRow))
          return false;
        if (!this.startRow.equals(that.startRow))
          return false;
      }

      boolean this_present_endRow = true && this.isSetEndRow();
      boolean that_present_endRow = true && that.isSetEndRow();
      if (this_present_endRow || that_present_endRow) {
        if (!(this_present_endRow && that_present_endRow))
          return false;
        if (!this.endRow.equals(that.endRow))
          return false;
      }

      boolean this_present_wait = true;
      boolean that_present_wait = true;
      if (this_present_wait || that_present_wait) {
        if (!(this_present_wait && that_present_wait))
          return false;
        if (this.wait != that.wait)
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
      if (isSetLogin())
        hashCode = hashCode * 8191 + login.hashCode();

      hashCode = hashCode * 8191 + ((isSetTableName()) ? 131071 : 524287);
      if (isSetTableName())
        hashCode = hashCode * 8191 + tableName.hashCode();

      hashCode = hashCode * 8191 + ((isSetStartRow()) ? 131071 : 524287);
      if (isSetStartRow())
        hashCode = hashCode * 8191 + startRow.hashCode();

      hashCode = hashCode * 8191 + ((isSetEndRow()) ? 131071 : 524287);
      if (isSetEndRow())
        hashCode = hashCode * 8191 + endRow.hashCode();

      hashCode = hashCode * 8191 + ((wait) ? 131071 : 524287);

      return hashCode;
    }

    @Override
    public int compareTo(flushTable_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLogin()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetTableName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.tableName, other.tableName);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetStartRow()).compareTo(other.isSetStartRow());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetStartRow()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.startRow, other.startRow);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetEndRow()).compareTo(other.isSetEndRow());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetEndRow()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.endRow, other.endRow);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetWait()).compareTo(other.isSetWait());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetWait()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.wait, other.wait);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("flushTable_args(");
      boolean first = true;

      sb.append("login:");
      if (this.login == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.login, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("tableName:");
      if (this.tableName == null) {
        sb.append("null");
      } else {
        sb.append(this.tableName);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("startRow:");
      if (this.startRow == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.startRow, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("endRow:");
      if (this.endRow == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.endRow, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("wait:");
      sb.append(this.wait);
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, 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;
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class flushTable_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public flushTable_argsStandardScheme getScheme() {
        return new flushTable_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // LOGIN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.login = iprot.readBinary();
                struct.setLoginIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // TABLE_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.tableName = iprot.readString();
                struct.setTableNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // START_ROW
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.startRow = iprot.readBinary();
                struct.setStartRowIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // END_ROW
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.endRow = iprot.readBinary();
                struct.setEndRowIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 5: // WAIT
              if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
                struct.wait = iprot.readBool();
                struct.setWaitIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, flushTable_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.login != null) {
          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
          oprot.writeBinary(struct.login);
          oprot.writeFieldEnd();
        }
        if (struct.tableName != null) {
          oprot.writeFieldBegin(TABLE_NAME_FIELD_DESC);
          oprot.writeString(struct.tableName);
          oprot.writeFieldEnd();
        }
        if (struct.startRow != null) {
          oprot.writeFieldBegin(START_ROW_FIELD_DESC);
          oprot.writeBinary(struct.startRow);
          oprot.writeFieldEnd();
        }
        if (struct.endRow != null) {
          oprot.writeFieldBegin(END_ROW_FIELD_DESC);
          oprot.writeBinary(struct.endRow);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldBegin(WAIT_FIELD_DESC);
        oprot.writeBool(struct.wait);
        oprot.writeFieldEnd();
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    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 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 {
        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);
        }
        if (struct.isSetTableName()) {
          optionals.set(1);
        }
        if (struct.isSetStartRow()) {
          optionals.set(2);
        }
        if (struct.isSetEndRow()) {
          optionals.set(3);
        }
        if (struct.isSetWait()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetLogin()) {
          oprot.writeBinary(struct.login);
        }
        if (struct.isSetTableName()) {
          oprot.writeString(struct.tableName);
        }
        if (struct.isSetStartRow()) {
          oprot.writeBinary(struct.startRow);
        }
        if (struct.isSetEndRow()) {
          oprot.writeBinary(struct.endRow);
        }
        if (struct.isSetWait()) {
          oprot.writeBool(struct.wait);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, flushTable_args struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.tableName = iprot.readString();
          struct.setTableNameIsSet(true);
        }
        if (incoming.get(2)) {
          struct.startRow = iprot.readBinary();
          struct.setStartRowIsSet(true);
        }
        if (incoming.get(3)) {
          struct.endRow = iprot.readBinary();
          struct.setEndRowIsSet(true);
        }
        if (incoming.get(4)) {
          struct.wait = iprot.readBool();
          struct.setWaitIsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("flushTable_result");

    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField OUCH3_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch3", org.apache.thrift.protocol.TType.STRUCT, (short)3);

    private static final org.apache.thrift.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
    public TableNotFoundException ouch3; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      OUCH1((short)1, "ouch1"),
      OUCH2((short)2, "ouch2"),
      OUCH3((short)3, "ouch3");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // OUCH1
            return OUCH1;
          case 2: // OUCH2
            return OUCH2;
          case 3: // OUCH3
            return OUCH3;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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.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.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);
    }

    public flushTable_result() {
    }

    public flushTable_result(
      AccumuloException ouch1,
      AccumuloSecurityException ouch2,
      TableNotFoundException ouch3)
    {
      this();
      this.ouch1 = ouch1;
      this.ouch2 = ouch2;
      this.ouch3 = ouch3;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public flushTable_result(flushTable_result other) {
      if (other.isSetOuch1()) {
        this.ouch1 = new AccumuloException(other.ouch1);
      }
      if (other.isSetOuch2()) {
        this.ouch2 = new AccumuloSecurityException(other.ouch2);
      }
      if (other.isSetOuch3()) {
        this.ouch3 = new TableNotFoundException(other.ouch3);
      }
    }

    public flushTable_result deepCopy() {
      return new flushTable_result(this);
    }

    @Override
    public void clear() {
      this.ouch1 = null;
      this.ouch2 = null;
      this.ouch3 = null;
    }

    public AccumuloException getOuch1() {
      return this.ouch1;
    }

    public flushTable_result setOuch1(AccumuloException ouch1) {
      this.ouch1 = ouch1;
      return this;
    }

    public void unsetOuch1() {
      this.ouch1 = null;
    }

    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch1() {
      return this.ouch1 != null;
    }

    public void setOuch1IsSet(boolean value) {
      if (!value) {
        this.ouch1 = null;
      }
    }

    public AccumuloSecurityException getOuch2() {
      return this.ouch2;
    }

    public flushTable_result setOuch2(AccumuloSecurityException ouch2) {
      this.ouch2 = ouch2;
      return this;
    }

    public void unsetOuch2() {
      this.ouch2 = null;
    }

    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch2() {
      return this.ouch2 != null;
    }

    public void setOuch2IsSet(boolean value) {
      if (!value) {
        this.ouch2 = null;
      }
    }

    public TableNotFoundException getOuch3() {
      return this.ouch3;
    }

    public flushTable_result setOuch3(TableNotFoundException ouch3) {
      this.ouch3 = ouch3;
      return this;
    }

    public void unsetOuch3() {
      this.ouch3 = null;
    }

    /** Returns true if field ouch3 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch3() {
      return this.ouch3 != null;
    }

    public void setOuch3IsSet(boolean value) {
      if (!value) {
        this.ouch3 = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case OUCH1:
        if (value == null) {
          unsetOuch1();
        } else {
          setOuch1((AccumuloException)value);
        }
        break;

      case OUCH2:
        if (value == null) {
          unsetOuch2();
        } else {
          setOuch2((AccumuloSecurityException)value);
        }
        break;

      case OUCH3:
        if (value == null) {
          unsetOuch3();
        } else {
          setOuch3((TableNotFoundException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case OUCH1:
        return getOuch1();

      case OUCH2:
        return getOuch2();

      case OUCH3:
        return getOuch3();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case OUCH1:
        return isSetOuch1();
      case OUCH2:
        return isSetOuch2();
      case OUCH3:
        return isSetOuch3();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof flushTable_result)
        return this.equals((flushTable_result)that);
      return false;
    }

    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();
      if (this_present_ouch1 || that_present_ouch1) {
        if (!(this_present_ouch1 && that_present_ouch1))
          return false;
        if (!this.ouch1.equals(that.ouch1))
          return false;
      }

      boolean this_present_ouch2 = true && this.isSetOuch2();
      boolean that_present_ouch2 = true && that.isSetOuch2();
      if (this_present_ouch2 || that_present_ouch2) {
        if (!(this_present_ouch2 && that_present_ouch2))
          return false;
        if (!this.ouch2.equals(that.ouch2))
          return false;
      }

      boolean this_present_ouch3 = true && this.isSetOuch3();
      boolean that_present_ouch3 = true && that.isSetOuch3();
      if (this_present_ouch3 || that_present_ouch3) {
        if (!(this_present_ouch3 && that_present_ouch3))
          return false;
        if (!this.ouch3.equals(that.ouch3))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
      if (isSetOuch1())
        hashCode = hashCode * 8191 + ouch1.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
      if (isSetOuch2())
        hashCode = hashCode * 8191 + ouch2.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
      if (isSetOuch3())
        hashCode = hashCode * 8191 + ouch3.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(flushTable_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch1()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch2()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch3()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch3, other.ouch3);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("flushTable_result(");
      boolean first = true;

      sb.append("ouch1:");
      if (this.ouch1 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch1);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch2:");
      if (this.ouch2 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch2);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch3:");
      if (this.ouch3 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch3);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class flushTable_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public flushTable_resultStandardScheme getScheme() {
        return new flushTable_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // OUCH1
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch1 = new AccumuloException();
                struct.ouch1.read(iprot);
                struct.setOuch1IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OUCH2
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch2 = new AccumuloSecurityException();
                struct.ouch2.read(iprot);
                struct.setOuch2IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // OUCH3
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch3 = new TableNotFoundException();
                struct.ouch3.read(iprot);
                struct.setOuch3IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, flushTable_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.ouch1 != null) {
          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
          struct.ouch1.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch2 != null) {
          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
          struct.ouch2.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch3 != null) {
          oprot.writeFieldBegin(OUCH3_FIELD_DESC);
          struct.ouch3.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class flushTable_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public flushTable_resultTupleScheme getScheme() {
        return new flushTable_resultTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetOuch2()) {
          optionals.set(1);
        }
        if (struct.isSetOuch3()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetOuch1()) {
          struct.ouch1.write(oprot);
        }
        if (struct.isSetOuch2()) {
          struct.ouch2.write(oprot);
        }
        if (struct.isSetOuch3()) {
          struct.ouch3.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, flushTable_result struct) throws org.apache.thrift.TException {
        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);
          struct.setOuch1IsSet(true);
        }
        if (incoming.get(1)) {
          struct.ouch2 = new AccumuloSecurityException();
          struct.ouch2.read(iprot);
          struct.setOuch2IsSet(true);
        }
        if (incoming.get(2)) {
          struct.ouch3 = new TableNotFoundException();
          struct.ouch3.read(iprot);
          struct.setOuch3IsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getDiskUsage_args");

    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField TABLES_FIELD_DESC = new org.apache.thrift.protocol.TField("tables", org.apache.thrift.protocol.TType.SET, (short)2);

    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 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 java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // LOGIN
            return LOGIN;
          case 2: // TABLES
            return TABLES;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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 = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getDiskUsage_args.class, metaDataMap);
    }

    public getDiskUsage_args() {
    }

    public getDiskUsage_args(
      java.nio.ByteBuffer login,
      java.util.Set<java.lang.String> tables)
    {
      this();
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      this.tables = tables;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getDiskUsage_args(getDiskUsage_args other) {
      if (other.isSetLogin()) {
        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
      }
      if (other.isSetTables()) {
        java.util.Set<java.lang.String> __this__tables = new java.util.HashSet<java.lang.String>(other.tables);
        this.tables = __this__tables;
      }
    }

    public getDiskUsage_args deepCopy() {
      return new getDiskUsage_args(this);
    }

    @Override
    public void clear() {
      this.login = null;
      this.tables = null;
    }

    public byte[] getLogin() {
      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
      return login == null ? null : login.array();
    }

    public java.nio.ByteBuffer bufferForLogin() {
      return org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    public getDiskUsage_args setLogin(byte[] login) {
      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
      return this;
    }

    public getDiskUsage_args setLogin(java.nio.ByteBuffer login) {
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      return this;
    }

    public void unsetLogin() {
      this.login = null;
    }

    /** Returns true if field login is set (has been assigned a value) and false otherwise */
    public boolean isSetLogin() {
      return this.login != null;
    }

    public void setLoginIsSet(boolean value) {
      if (!value) {
        this.login = null;
      }
    }

    public int getTablesSize() {
      return (this.tables == null) ? 0 : this.tables.size();
    }

    public java.util.Iterator<java.lang.String> getTablesIterator() {
      return (this.tables == null) ? null : this.tables.iterator();
    }

    public void addToTables(java.lang.String elem) {
      if (this.tables == null) {
        this.tables = new java.util.HashSet<java.lang.String>();
      }
      this.tables.add(elem);
    }

    public java.util.Set<java.lang.String> getTables() {
      return this.tables;
    }

    public getDiskUsage_args setTables(java.util.Set<java.lang.String> tables) {
      this.tables = tables;
      return this;
    }

    public void unsetTables() {
      this.tables = null;
    }

    /** Returns true if field tables is set (has been assigned a value) and false otherwise */
    public boolean isSetTables() {
      return this.tables != null;
    }

    public void setTablesIsSet(boolean value) {
      if (!value) {
        this.tables = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case LOGIN:
        if (value == null) {
          unsetLogin();
        } else {
          if (value instanceof byte[]) {
            setLogin((byte[])value);
          } else {
            setLogin((java.nio.ByteBuffer)value);
          }
        }
        break;

      case TABLES:
        if (value == null) {
          unsetTables();
        } else {
          setTables((java.util.Set<java.lang.String>)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case LOGIN:
        return getLogin();

      case TABLES:
        return getTables();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case LOGIN:
        return isSetLogin();
      case TABLES:
        return isSetTables();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof getDiskUsage_args)
        return this.equals((getDiskUsage_args)that);
      return false;
    }

    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();
      if (this_present_login || that_present_login) {
        if (!(this_present_login && that_present_login))
          return false;
        if (!this.login.equals(that.login))
          return false;
      }

      boolean this_present_tables = true && this.isSetTables();
      boolean that_present_tables = true && that.isSetTables();
      if (this_present_tables || that_present_tables) {
        if (!(this_present_tables && that_present_tables))
          return false;
        if (!this.tables.equals(that.tables))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
      if (isSetLogin())
        hashCode = hashCode * 8191 + login.hashCode();

      hashCode = hashCode * 8191 + ((isSetTables()) ? 131071 : 524287);
      if (isSetTables())
        hashCode = hashCode * 8191 + tables.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(getDiskUsage_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLogin()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetTables()).compareTo(other.isSetTables());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetTables()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.tables, other.tables);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("getDiskUsage_args(");
      boolean first = true;

      sb.append("login:");
      if (this.login == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.login, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("tables:");
      if (this.tables == null) {
        sb.append("null");
      } else {
        sb.append(this.tables);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class getDiskUsage_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getDiskUsage_argsStandardScheme getScheme() {
        return new getDiskUsage_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // LOGIN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.login = iprot.readBinary();
                struct.setLoginIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // TABLES
              if (schemeField.type == org.apache.thrift.protocol.TType.SET) {
                {
                  org.apache.thrift.protocol.TSet _set224 = iprot.readSetBegin();
                  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();
                    struct.tables.add(_elem225);
                  }
                  iprot.readSetEnd();
                }
                struct.setTablesIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getDiskUsage_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.login != null) {
          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
          oprot.writeBinary(struct.login);
          oprot.writeFieldEnd();
        }
        if (struct.tables != null) {
          oprot.writeFieldBegin(TABLES_FIELD_DESC);
          {
            oprot.writeSetBegin(new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRING, struct.tables.size()));
            for (java.lang.String _iter227 : struct.tables)
            {
              oprot.writeString(_iter227);
            }
            oprot.writeSetEnd();
          }
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    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 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 {
        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);
        }
        if (struct.isSetTables()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetLogin()) {
          oprot.writeBinary(struct.login);
        }
        if (struct.isSetTables()) {
          {
            oprot.writeI32(struct.tables.size());
            for (java.lang.String _iter228 : struct.tables)
            {
              oprot.writeString(_iter228);
            }
          }
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getDiskUsage_args struct) throws org.apache.thrift.TException {
        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);
        }
        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 java.util.HashSet<java.lang.String>(2*_set229.size);
            java.lang.String _elem230;
            for (int _i231 = 0; _i231 < _set229.size; ++_i231)
            {
              _elem230 = iprot.readString();
              struct.tables.add(_elem230);
            }
          }
          struct.setTablesIsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getDiskUsage_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.LIST, (short)0);
    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final 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.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new getDiskUsage_resultStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new getDiskUsage_resultTupleSchemeFactory();

    public java.util.List<DiskUsage> success; // required
    public AccumuloException ouch1; // required
    public AccumuloSecurityException ouch2; // required
    public TableNotFoundException ouch3; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      OUCH1((short)1, "ouch1"),
      OUCH2((short)2, "ouch2"),
      OUCH3((short)3, "ouch3");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // OUCH1
            return OUCH1;
          case 2: // OUCH2
            return OUCH2;
          case 3: // OUCH3
            return OUCH3;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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.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.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);
    }

    public getDiskUsage_result() {
    }

    public getDiskUsage_result(
      java.util.List<DiskUsage> success,
      AccumuloException ouch1,
      AccumuloSecurityException ouch2,
      TableNotFoundException ouch3)
    {
      this();
      this.success = success;
      this.ouch1 = ouch1;
      this.ouch2 = ouch2;
      this.ouch3 = ouch3;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getDiskUsage_result(getDiskUsage_result other) {
      if (other.isSetSuccess()) {
        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));
        }
        this.success = __this__success;
      }
      if (other.isSetOuch1()) {
        this.ouch1 = new AccumuloException(other.ouch1);
      }
      if (other.isSetOuch2()) {
        this.ouch2 = new AccumuloSecurityException(other.ouch2);
      }
      if (other.isSetOuch3()) {
        this.ouch3 = new TableNotFoundException(other.ouch3);
      }
    }

    public getDiskUsage_result deepCopy() {
      return new getDiskUsage_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ouch1 = null;
      this.ouch2 = null;
      this.ouch3 = null;
    }

    public int getSuccessSize() {
      return (this.success == null) ? 0 : this.success.size();
    }

    public java.util.Iterator<DiskUsage> getSuccessIterator() {
      return (this.success == null) ? null : this.success.iterator();
    }

    public void addToSuccess(DiskUsage elem) {
      if (this.success == null) {
        this.success = new java.util.ArrayList<DiskUsage>();
      }
      this.success.add(elem);
    }

    public java.util.List<DiskUsage> getSuccess() {
      return this.success;
    }

    public getDiskUsage_result setSuccess(java.util.List<DiskUsage> success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return this.success != null;
    }

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public AccumuloException getOuch1() {
      return this.ouch1;
    }

    public getDiskUsage_result setOuch1(AccumuloException ouch1) {
      this.ouch1 = ouch1;
      return this;
    }

    public void unsetOuch1() {
      this.ouch1 = null;
    }

    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch1() {
      return this.ouch1 != null;
    }

    public void setOuch1IsSet(boolean value) {
      if (!value) {
        this.ouch1 = null;
      }
    }

    public AccumuloSecurityException getOuch2() {
      return this.ouch2;
    }

    public getDiskUsage_result setOuch2(AccumuloSecurityException ouch2) {
      this.ouch2 = ouch2;
      return this;
    }

    public void unsetOuch2() {
      this.ouch2 = null;
    }

    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch2() {
      return this.ouch2 != null;
    }

    public void setOuch2IsSet(boolean value) {
      if (!value) {
        this.ouch2 = null;
      }
    }

    public TableNotFoundException getOuch3() {
      return this.ouch3;
    }

    public getDiskUsage_result setOuch3(TableNotFoundException ouch3) {
      this.ouch3 = ouch3;
      return this;
    }

    public void unsetOuch3() {
      this.ouch3 = null;
    }

    /** Returns true if field ouch3 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch3() {
      return this.ouch3 != null;
    }

    public void setOuch3IsSet(boolean value) {
      if (!value) {
        this.ouch3 = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.util.List<DiskUsage>)value);
        }
        break;

      case OUCH1:
        if (value == null) {
          unsetOuch1();
        } else {
          setOuch1((AccumuloException)value);
        }
        break;

      case OUCH2:
        if (value == null) {
          unsetOuch2();
        } else {
          setOuch2((AccumuloSecurityException)value);
        }
        break;

      case OUCH3:
        if (value == null) {
          unsetOuch3();
        } else {
          setOuch3((TableNotFoundException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case OUCH1:
        return getOuch1();

      case OUCH2:
        return getOuch2();

      case OUCH3:
        return getOuch3();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case OUCH1:
        return isSetOuch1();
      case OUCH2:
        return isSetOuch2();
      case OUCH3:
        return isSetOuch3();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof getDiskUsage_result)
        return this.equals((getDiskUsage_result)that);
      return false;
    }

    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();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ouch1 = true && this.isSetOuch1();
      boolean that_present_ouch1 = true && that.isSetOuch1();
      if (this_present_ouch1 || that_present_ouch1) {
        if (!(this_present_ouch1 && that_present_ouch1))
          return false;
        if (!this.ouch1.equals(that.ouch1))
          return false;
      }

      boolean this_present_ouch2 = true && this.isSetOuch2();
      boolean that_present_ouch2 = true && that.isSetOuch2();
      if (this_present_ouch2 || that_present_ouch2) {
        if (!(this_present_ouch2 && that_present_ouch2))
          return false;
        if (!this.ouch2.equals(that.ouch2))
          return false;
      }

      boolean this_present_ouch3 = true && this.isSetOuch3();
      boolean that_present_ouch3 = true && that.isSetOuch3();
      if (this_present_ouch3 || that_present_ouch3) {
        if (!(this_present_ouch3 && that_present_ouch3))
          return false;
        if (!this.ouch3.equals(that.ouch3))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
      if (isSetSuccess())
        hashCode = hashCode * 8191 + success.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
      if (isSetOuch1())
        hashCode = hashCode * 8191 + ouch1.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
      if (isSetOuch2())
        hashCode = hashCode * 8191 + ouch2.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
      if (isSetOuch3())
        hashCode = hashCode * 8191 + ouch3.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(getDiskUsage_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch1()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch2()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch3()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch3, other.ouch3);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("getDiskUsage_result(");
      boolean first = true;

      sb.append("success:");
      if (this.success == null) {
        sb.append("null");
      } else {
        sb.append(this.success);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch1:");
      if (this.ouch1 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch1);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch2:");
      if (this.ouch2 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch2);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch3:");
      if (this.ouch3 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch3);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class getDiskUsage_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getDiskUsage_resultStandardScheme getScheme() {
        return new getDiskUsage_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
                {
                  org.apache.thrift.protocol.TList _list232 = iprot.readListBegin();
                  struct.success = new java.util.ArrayList<DiskUsage>(_list232.size);
                  DiskUsage _elem233;
                  for (int _i234 = 0; _i234 < _list232.size; ++_i234)
                  {
                    _elem233 = new DiskUsage();
                    _elem233.read(iprot);
                    struct.success.add(_elem233);
                  }
                  iprot.readListEnd();
                }
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // OUCH1
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch1 = new AccumuloException();
                struct.ouch1.read(iprot);
                struct.setOuch1IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OUCH2
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch2 = new AccumuloSecurityException();
                struct.ouch2.read(iprot);
                struct.setOuch2IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // OUCH3
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch3 = new TableNotFoundException();
                struct.ouch3.read(iprot);
                struct.setOuch3IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getDiskUsage_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, struct.success.size()));
            for (DiskUsage _iter235 : struct.success)
            {
              _iter235.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.ouch1 != null) {
          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
          struct.ouch1.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch2 != null) {
          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
          struct.ouch2.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch3 != null) {
          oprot.writeFieldBegin(OUCH3_FIELD_DESC);
          struct.ouch3.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    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 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 {
        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);
        }
        if (struct.isSetOuch1()) {
          optionals.set(1);
        }
        if (struct.isSetOuch2()) {
          optionals.set(2);
        }
        if (struct.isSetOuch3()) {
          optionals.set(3);
        }
        oprot.writeBitSet(optionals, 4);
        if (struct.isSetSuccess()) {
          {
            oprot.writeI32(struct.success.size());
            for (DiskUsage _iter236 : struct.success)
            {
              _iter236.write(oprot);
            }
          }
        }
        if (struct.isSetOuch1()) {
          struct.ouch1.write(oprot);
        }
        if (struct.isSetOuch2()) {
          struct.ouch2.write(oprot);
        }
        if (struct.isSetOuch3()) {
          struct.ouch3.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getDiskUsage_result struct) throws org.apache.thrift.TException {
        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 java.util.ArrayList<DiskUsage>(_list237.size);
            DiskUsage _elem238;
            for (int _i239 = 0; _i239 < _list237.size; ++_i239)
            {
              _elem238 = new DiskUsage();
              _elem238.read(iprot);
              struct.success.add(_elem238);
            }
          }
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ouch1 = new AccumuloException();
          struct.ouch1.read(iprot);
          struct.setOuch1IsSet(true);
        }
        if (incoming.get(2)) {
          struct.ouch2 = new AccumuloSecurityException();
          struct.ouch2.read(iprot);
          struct.setOuch2IsSet(true);
        }
        if (incoming.get(3)) {
          struct.ouch3 = new TableNotFoundException();
          struct.ouch3.read(iprot);
          struct.setOuch3IsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getLocalityGroups_args");

    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField 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.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new getLocalityGroups_argsStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new getLocalityGroups_argsTupleSchemeFactory();

    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 java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // LOGIN
            return LOGIN;
          case 2: // TABLE_NAME
            return TABLE_NAME;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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 = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getLocalityGroups_args.class, metaDataMap);
    }

    public getLocalityGroups_args() {
    }

    public getLocalityGroups_args(
      java.nio.ByteBuffer login,
      java.lang.String tableName)
    {
      this();
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      this.tableName = tableName;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getLocalityGroups_args(getLocalityGroups_args other) {
      if (other.isSetLogin()) {
        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
      }
      if (other.isSetTableName()) {
        this.tableName = other.tableName;
      }
    }

    public getLocalityGroups_args deepCopy() {
      return new getLocalityGroups_args(this);
    }

    @Override
    public void clear() {
      this.login = null;
      this.tableName = null;
    }

    public byte[] getLogin() {
      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
      return login == null ? null : login.array();
    }

    public java.nio.ByteBuffer bufferForLogin() {
      return org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    public getLocalityGroups_args setLogin(byte[] login) {
      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
      return this;
    }

    public getLocalityGroups_args setLogin(java.nio.ByteBuffer login) {
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      return this;
    }

    public void unsetLogin() {
      this.login = null;
    }

    /** Returns true if field login is set (has been assigned a value) and false otherwise */
    public boolean isSetLogin() {
      return this.login != null;
    }

    public void setLoginIsSet(boolean value) {
      if (!value) {
        this.login = null;
      }
    }

    public java.lang.String getTableName() {
      return this.tableName;
    }

    public getLocalityGroups_args setTableName(java.lang.String tableName) {
      this.tableName = tableName;
      return this;
    }

    public void unsetTableName() {
      this.tableName = null;
    }

    /** Returns true if field tableName is set (has been assigned a value) and false otherwise */
    public boolean isSetTableName() {
      return this.tableName != null;
    }

    public void setTableNameIsSet(boolean value) {
      if (!value) {
        this.tableName = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case LOGIN:
        if (value == null) {
          unsetLogin();
        } else {
          if (value instanceof byte[]) {
            setLogin((byte[])value);
          } else {
            setLogin((java.nio.ByteBuffer)value);
          }
        }
        break;

      case TABLE_NAME:
        if (value == null) {
          unsetTableName();
        } else {
          setTableName((java.lang.String)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case LOGIN:
        return getLogin();

      case TABLE_NAME:
        return getTableName();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case LOGIN:
        return isSetLogin();
      case TABLE_NAME:
        return isSetTableName();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof getLocalityGroups_args)
        return this.equals((getLocalityGroups_args)that);
      return false;
    }

    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();
      if (this_present_login || that_present_login) {
        if (!(this_present_login && that_present_login))
          return false;
        if (!this.login.equals(that.login))
          return false;
      }

      boolean this_present_tableName = true && this.isSetTableName();
      boolean that_present_tableName = true && that.isSetTableName();
      if (this_present_tableName || that_present_tableName) {
        if (!(this_present_tableName && that_present_tableName))
          return false;
        if (!this.tableName.equals(that.tableName))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
      if (isSetLogin())
        hashCode = hashCode * 8191 + login.hashCode();

      hashCode = hashCode * 8191 + ((isSetTableName()) ? 131071 : 524287);
      if (isSetTableName())
        hashCode = hashCode * 8191 + tableName.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(getLocalityGroups_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLogin()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetTableName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.tableName, other.tableName);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("getLocalityGroups_args(");
      boolean first = true;

      sb.append("login:");
      if (this.login == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.login, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("tableName:");
      if (this.tableName == null) {
        sb.append("null");
      } else {
        sb.append(this.tableName);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class getLocalityGroups_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getLocalityGroups_argsStandardScheme getScheme() {
        return new getLocalityGroups_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // LOGIN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.login = iprot.readBinary();
                struct.setLoginIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // TABLE_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.tableName = iprot.readString();
                struct.setTableNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getLocalityGroups_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.login != null) {
          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
          oprot.writeBinary(struct.login);
          oprot.writeFieldEnd();
        }
        if (struct.tableName != null) {
          oprot.writeFieldBegin(TABLE_NAME_FIELD_DESC);
          oprot.writeString(struct.tableName);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    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 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 {
        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);
        }
        if (struct.isSetTableName()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetLogin()) {
          oprot.writeBinary(struct.login);
        }
        if (struct.isSetTableName()) {
          oprot.writeString(struct.tableName);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getLocalityGroups_args struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.tableName = iprot.readString();
          struct.setTableNameIsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getLocalityGroups_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.MAP, (short)0);
    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField OUCH3_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch3", org.apache.thrift.protocol.TType.STRUCT, (short)3);

    private static final 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 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

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      OUCH1((short)1, "ouch1"),
      OUCH2((short)2, "ouch2"),
      OUCH3((short)3, "ouch3");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // OUCH1
            return OUCH1;
          case 2: // OUCH2
            return OUCH2;
          case 3: // OUCH3
            return OUCH3;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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.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.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);
    }

    public getLocalityGroups_result() {
    }

    public getLocalityGroups_result(
      java.util.Map<java.lang.String,java.util.Set<java.lang.String>> success,
      AccumuloException ouch1,
      AccumuloSecurityException ouch2,
      TableNotFoundException ouch3)
    {
      this();
      this.success = success;
      this.ouch1 = ouch1;
      this.ouch2 = ouch2;
      this.ouch3 = ouch3;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getLocalityGroups_result(getLocalityGroups_result other) {
      if (other.isSetSuccess()) {
        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()) {

          java.lang.String other_element_key = other_element.getKey();
          java.util.Set<java.lang.String> other_element_value = other_element.getValue();

          java.lang.String __this__success_copy_key = other_element_key;

          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);
        }
        this.success = __this__success;
      }
      if (other.isSetOuch1()) {
        this.ouch1 = new AccumuloException(other.ouch1);
      }
      if (other.isSetOuch2()) {
        this.ouch2 = new AccumuloSecurityException(other.ouch2);
      }
      if (other.isSetOuch3()) {
        this.ouch3 = new TableNotFoundException(other.ouch3);
      }
    }

    public getLocalityGroups_result deepCopy() {
      return new getLocalityGroups_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ouch1 = null;
      this.ouch2 = null;
      this.ouch3 = null;
    }

    public int getSuccessSize() {
      return (this.success == null) ? 0 : this.success.size();
    }

    public void putToSuccess(java.lang.String key, java.util.Set<java.lang.String> val) {
      if (this.success == null) {
        this.success = new java.util.HashMap<java.lang.String,java.util.Set<java.lang.String>>();
      }
      this.success.put(key, val);
    }

    public java.util.Map<java.lang.String,java.util.Set<java.lang.String>> getSuccess() {
      return this.success;
    }

    public getLocalityGroups_result setSuccess(java.util.Map<java.lang.String,java.util.Set<java.lang.String>> success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return this.success != null;
    }

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public AccumuloException getOuch1() {
      return this.ouch1;
    }

    public getLocalityGroups_result setOuch1(AccumuloException ouch1) {
      this.ouch1 = ouch1;
      return this;
    }

    public void unsetOuch1() {
      this.ouch1 = null;
    }

    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch1() {
      return this.ouch1 != null;
    }

    public void setOuch1IsSet(boolean value) {
      if (!value) {
        this.ouch1 = null;
      }
    }

    public AccumuloSecurityException getOuch2() {
      return this.ouch2;
    }

    public getLocalityGroups_result setOuch2(AccumuloSecurityException ouch2) {
      this.ouch2 = ouch2;
      return this;
    }

    public void unsetOuch2() {
      this.ouch2 = null;
    }

    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch2() {
      return this.ouch2 != null;
    }

    public void setOuch2IsSet(boolean value) {
      if (!value) {
        this.ouch2 = null;
      }
    }

    public TableNotFoundException getOuch3() {
      return this.ouch3;
    }

    public getLocalityGroups_result setOuch3(TableNotFoundException ouch3) {
      this.ouch3 = ouch3;
      return this;
    }

    public void unsetOuch3() {
      this.ouch3 = null;
    }

    /** Returns true if field ouch3 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch3() {
      return this.ouch3 != null;
    }

    public void setOuch3IsSet(boolean value) {
      if (!value) {
        this.ouch3 = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.util.Map<java.lang.String,java.util.Set<java.lang.String>>)value);
        }
        break;

      case OUCH1:
        if (value == null) {
          unsetOuch1();
        } else {
          setOuch1((AccumuloException)value);
        }
        break;

      case OUCH2:
        if (value == null) {
          unsetOuch2();
        } else {
          setOuch2((AccumuloSecurityException)value);
        }
        break;

      case OUCH3:
        if (value == null) {
          unsetOuch3();
        } else {
          setOuch3((TableNotFoundException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case OUCH1:
        return getOuch1();

      case OUCH2:
        return getOuch2();

      case OUCH3:
        return getOuch3();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case OUCH1:
        return isSetOuch1();
      case OUCH2:
        return isSetOuch2();
      case OUCH3:
        return isSetOuch3();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof getLocalityGroups_result)
        return this.equals((getLocalityGroups_result)that);
      return false;
    }

    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();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ouch1 = true && this.isSetOuch1();
      boolean that_present_ouch1 = true && that.isSetOuch1();
      if (this_present_ouch1 || that_present_ouch1) {
        if (!(this_present_ouch1 && that_present_ouch1))
          return false;
        if (!this.ouch1.equals(that.ouch1))
          return false;
      }

      boolean this_present_ouch2 = true && this.isSetOuch2();
      boolean that_present_ouch2 = true && that.isSetOuch2();
      if (this_present_ouch2 || that_present_ouch2) {
        if (!(this_present_ouch2 && that_present_ouch2))
          return false;
        if (!this.ouch2.equals(that.ouch2))
          return false;
      }

      boolean this_present_ouch3 = true && this.isSetOuch3();
      boolean that_present_ouch3 = true && that.isSetOuch3();
      if (this_present_ouch3 || that_present_ouch3) {
        if (!(this_present_ouch3 && that_present_ouch3))
          return false;
        if (!this.ouch3.equals(that.ouch3))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
      if (isSetSuccess())
        hashCode = hashCode * 8191 + success.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
      if (isSetOuch1())
        hashCode = hashCode * 8191 + ouch1.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
      if (isSetOuch2())
        hashCode = hashCode * 8191 + ouch2.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
      if (isSetOuch3())
        hashCode = hashCode * 8191 + ouch3.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(getLocalityGroups_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch1()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch2()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch3()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch3, other.ouch3);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("getLocalityGroups_result(");
      boolean first = true;

      sb.append("success:");
      if (this.success == null) {
        sb.append("null");
      } else {
        sb.append(this.success);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch1:");
      if (this.ouch1 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch1);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch2:");
      if (this.ouch2 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch2);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch3:");
      if (this.ouch3 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch3);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class getLocalityGroups_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getLocalityGroups_resultStandardScheme getScheme() {
        return new getLocalityGroups_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.MAP) {
                {
                  org.apache.thrift.protocol.TMap _map240 = iprot.readMapBegin();
                  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 java.util.HashSet<java.lang.String>(2*_set244.size);
                      java.lang.String _elem245;
                      for (int _i246 = 0; _i246 < _set244.size; ++_i246)
                      {
                        _elem245 = iprot.readString();
                        _val242.add(_elem245);
                      }
                      iprot.readSetEnd();
                    }
                    struct.success.put(_key241, _val242);
                  }
                  iprot.readMapEnd();
                }
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // OUCH1
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch1 = new AccumuloException();
                struct.ouch1.read(iprot);
                struct.setOuch1IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OUCH2
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch2 = new AccumuloSecurityException();
                struct.ouch2.read(iprot);
                struct.setOuch2IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // OUCH3
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch3 = new TableNotFoundException();
                struct.ouch3.read(iprot);
                struct.setOuch3IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getLocalityGroups_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          {
            oprot.writeMapBegin(new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.SET, struct.success.size()));
            for (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 (java.lang.String _iter248 : _iter247.getValue())
                {
                  oprot.writeString(_iter248);
                }
                oprot.writeSetEnd();
              }
            }
            oprot.writeMapEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.ouch1 != null) {
          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
          struct.ouch1.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch2 != null) {
          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
          struct.ouch2.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch3 != null) {
          oprot.writeFieldBegin(OUCH3_FIELD_DESC);
          struct.ouch3.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getLocalityGroups_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getLocalityGroups_resultTupleScheme getScheme() {
        return new getLocalityGroups_resultTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetOuch1()) {
          optionals.set(1);
        }
        if (struct.isSetOuch2()) {
          optionals.set(2);
        }
        if (struct.isSetOuch3()) {
          optionals.set(3);
        }
        oprot.writeBitSet(optionals, 4);
        if (struct.isSetSuccess()) {
          {
            oprot.writeI32(struct.success.size());
            for (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 (java.lang.String _iter250 : _iter249.getValue())
                {
                  oprot.writeString(_iter250);
                }
              }
            }
          }
        }
        if (struct.isSetOuch1()) {
          struct.ouch1.write(oprot);
        }
        if (struct.isSetOuch2()) {
          struct.ouch2.write(oprot);
        }
        if (struct.isSetOuch3()) {
          struct.ouch3.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getLocalityGroups_result struct) throws org.apache.thrift.TException {
        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 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 java.util.HashSet<java.lang.String>(2*_set255.size);
                java.lang.String _elem256;
                for (int _i257 = 0; _i257 < _set255.size; ++_i257)
                {
                  _elem256 = iprot.readString();
                  _val253.add(_elem256);
                }
              }
              struct.success.put(_key252, _val253);
            }
          }
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ouch1 = new AccumuloException();
          struct.ouch1.read(iprot);
          struct.setOuch1IsSet(true);
        }
        if (incoming.get(2)) {
          struct.ouch2 = new AccumuloSecurityException();
          struct.ouch2.read(iprot);
          struct.setOuch2IsSet(true);
        }
        if (incoming.get(3)) {
          struct.ouch3 = new TableNotFoundException();
          struct.ouch3.read(iprot);
          struct.setOuch3IsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getIteratorSetting_args");

    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField 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 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 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 java.nio.ByteBuffer login; // required
    public java.lang.String tableName; // required
    public java.lang.String iteratorName; // required
    /**
     * 
     * @see IteratorScope
     */
    public IteratorScope scope; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      LOGIN((short)1, "login"),
      TABLE_NAME((short)2, "tableName"),
      ITERATOR_NAME((short)3, "iteratorName"),
      /**
       * 
       * @see IteratorScope
       */
      SCOPE((short)4, "scope");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // LOGIN
            return LOGIN;
          case 2: // TABLE_NAME
            return TABLE_NAME;
          case 3: // ITERATOR_NAME
            return ITERATOR_NAME;
          case 4: // SCOPE
            return SCOPE;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.ITERATOR_NAME, new org.apache.thrift.meta_data.FieldMetaData("iteratorName", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.SCOPE, new org.apache.thrift.meta_data.FieldMetaData("scope", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, IteratorScope.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getIteratorSetting_args.class, metaDataMap);
    }

    public getIteratorSetting_args() {
    }

    public getIteratorSetting_args(
      java.nio.ByteBuffer login,
      java.lang.String tableName,
      java.lang.String iteratorName,
      IteratorScope scope)
    {
      this();
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      this.tableName = tableName;
      this.iteratorName = iteratorName;
      this.scope = scope;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getIteratorSetting_args(getIteratorSetting_args other) {
      if (other.isSetLogin()) {
        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
      }
      if (other.isSetTableName()) {
        this.tableName = other.tableName;
      }
      if (other.isSetIteratorName()) {
        this.iteratorName = other.iteratorName;
      }
      if (other.isSetScope()) {
        this.scope = other.scope;
      }
    }

    public getIteratorSetting_args deepCopy() {
      return new getIteratorSetting_args(this);
    }

    @Override
    public void clear() {
      this.login = null;
      this.tableName = null;
      this.iteratorName = null;
      this.scope = null;
    }

    public byte[] getLogin() {
      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
      return login == null ? null : login.array();
    }

    public java.nio.ByteBuffer bufferForLogin() {
      return org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    public getIteratorSetting_args setLogin(byte[] login) {
      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
      return this;
    }

    public getIteratorSetting_args setLogin(java.nio.ByteBuffer login) {
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      return this;
    }

    public void unsetLogin() {
      this.login = null;
    }

    /** Returns true if field login is set (has been assigned a value) and false otherwise */
    public boolean isSetLogin() {
      return this.login != null;
    }

    public void setLoginIsSet(boolean value) {
      if (!value) {
        this.login = null;
      }
    }

    public java.lang.String getTableName() {
      return this.tableName;
    }

    public getIteratorSetting_args setTableName(java.lang.String tableName) {
      this.tableName = tableName;
      return this;
    }

    public void unsetTableName() {
      this.tableName = null;
    }

    /** Returns true if field tableName is set (has been assigned a value) and false otherwise */
    public boolean isSetTableName() {
      return this.tableName != null;
    }

    public void setTableNameIsSet(boolean value) {
      if (!value) {
        this.tableName = null;
      }
    }

    public java.lang.String getIteratorName() {
      return this.iteratorName;
    }

    public getIteratorSetting_args setIteratorName(java.lang.String iteratorName) {
      this.iteratorName = iteratorName;
      return this;
    }

    public void unsetIteratorName() {
      this.iteratorName = null;
    }

    /** Returns true if field iteratorName is set (has been assigned a value) and false otherwise */
    public boolean isSetIteratorName() {
      return this.iteratorName != null;
    }

    public void setIteratorNameIsSet(boolean value) {
      if (!value) {
        this.iteratorName = null;
      }
    }

    /**
     * 
     * @see IteratorScope
     */
    public IteratorScope getScope() {
      return this.scope;
    }

    /**
     * 
     * @see IteratorScope
     */
    public getIteratorSetting_args setScope(IteratorScope scope) {
      this.scope = scope;
      return this;
    }

    public void unsetScope() {
      this.scope = null;
    }

    /** Returns true if field scope is set (has been assigned a value) and false otherwise */
    public boolean isSetScope() {
      return this.scope != null;
    }

    public void setScopeIsSet(boolean value) {
      if (!value) {
        this.scope = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case LOGIN:
        if (value == null) {
          unsetLogin();
        } else {
          if (value instanceof byte[]) {
            setLogin((byte[])value);
          } else {
            setLogin((java.nio.ByteBuffer)value);
          }
        }
        break;

      case TABLE_NAME:
        if (value == null) {
          unsetTableName();
        } else {
          setTableName((java.lang.String)value);
        }
        break;

      case ITERATOR_NAME:
        if (value == null) {
          unsetIteratorName();
        } else {
          setIteratorName((java.lang.String)value);
        }
        break;

      case SCOPE:
        if (value == null) {
          unsetScope();
        } else {
          setScope((IteratorScope)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case LOGIN:
        return getLogin();

      case TABLE_NAME:
        return getTableName();

      case ITERATOR_NAME:
        return getIteratorName();

      case SCOPE:
        return getScope();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case LOGIN:
        return isSetLogin();
      case TABLE_NAME:
        return isSetTableName();
      case ITERATOR_NAME:
        return isSetIteratorName();
      case SCOPE:
        return isSetScope();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof getIteratorSetting_args)
        return this.equals((getIteratorSetting_args)that);
      return false;
    }

    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();
      if (this_present_login || that_present_login) {
        if (!(this_present_login && that_present_login))
          return false;
        if (!this.login.equals(that.login))
          return false;
      }

      boolean this_present_tableName = true && this.isSetTableName();
      boolean that_present_tableName = true && that.isSetTableName();
      if (this_present_tableName || that_present_tableName) {
        if (!(this_present_tableName && that_present_tableName))
          return false;
        if (!this.tableName.equals(that.tableName))
          return false;
      }

      boolean this_present_iteratorName = true && this.isSetIteratorName();
      boolean that_present_iteratorName = true && that.isSetIteratorName();
      if (this_present_iteratorName || that_present_iteratorName) {
        if (!(this_present_iteratorName && that_present_iteratorName))
          return false;
        if (!this.iteratorName.equals(that.iteratorName))
          return false;
      }

      boolean this_present_scope = true && this.isSetScope();
      boolean that_present_scope = true && that.isSetScope();
      if (this_present_scope || that_present_scope) {
        if (!(this_present_scope && that_present_scope))
          return false;
        if (!this.scope.equals(that.scope))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
      if (isSetLogin())
        hashCode = hashCode * 8191 + login.hashCode();

      hashCode = hashCode * 8191 + ((isSetTableName()) ? 131071 : 524287);
      if (isSetTableName())
        hashCode = hashCode * 8191 + tableName.hashCode();

      hashCode = hashCode * 8191 + ((isSetIteratorName()) ? 131071 : 524287);
      if (isSetIteratorName())
        hashCode = hashCode * 8191 + iteratorName.hashCode();

      hashCode = hashCode * 8191 + ((isSetScope()) ? 131071 : 524287);
      if (isSetScope())
        hashCode = hashCode * 8191 + scope.getValue();

      return hashCode;
    }

    @Override
    public int compareTo(getIteratorSetting_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLogin()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetTableName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.tableName, other.tableName);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetIteratorName()).compareTo(other.isSetIteratorName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIteratorName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.iteratorName, other.iteratorName);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetScope()).compareTo(other.isSetScope());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetScope()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.scope, other.scope);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("getIteratorSetting_args(");
      boolean first = true;

      sb.append("login:");
      if (this.login == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.login, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("tableName:");
      if (this.tableName == null) {
        sb.append("null");
      } else {
        sb.append(this.tableName);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("iteratorName:");
      if (this.iteratorName == null) {
        sb.append("null");
      } else {
        sb.append(this.iteratorName);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("scope:");
      if (this.scope == null) {
        sb.append("null");
      } else {
        sb.append(this.scope);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class getIteratorSetting_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getIteratorSetting_argsStandardScheme getScheme() {
        return new getIteratorSetting_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // LOGIN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.login = iprot.readBinary();
                struct.setLoginIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // TABLE_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.tableName = iprot.readString();
                struct.setTableNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ITERATOR_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.iteratorName = iprot.readString();
                struct.setIteratorNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // SCOPE
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.scope = org.apache.accumulo.proxy.thrift.IteratorScope.findByValue(iprot.readI32());
                struct.setScopeIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getIteratorSetting_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.login != null) {
          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
          oprot.writeBinary(struct.login);
          oprot.writeFieldEnd();
        }
        if (struct.tableName != null) {
          oprot.writeFieldBegin(TABLE_NAME_FIELD_DESC);
          oprot.writeString(struct.tableName);
          oprot.writeFieldEnd();
        }
        if (struct.iteratorName != null) {
          oprot.writeFieldBegin(ITERATOR_NAME_FIELD_DESC);
          oprot.writeString(struct.iteratorName);
          oprot.writeFieldEnd();
        }
        if (struct.scope != null) {
          oprot.writeFieldBegin(SCOPE_FIELD_DESC);
          oprot.writeI32(struct.scope.getValue());
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getIteratorSetting_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getIteratorSetting_argsTupleScheme getScheme() {
        return new getIteratorSetting_argsTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetTableName()) {
          optionals.set(1);
        }
        if (struct.isSetIteratorName()) {
          optionals.set(2);
        }
        if (struct.isSetScope()) {
          optionals.set(3);
        }
        oprot.writeBitSet(optionals, 4);
        if (struct.isSetLogin()) {
          oprot.writeBinary(struct.login);
        }
        if (struct.isSetTableName()) {
          oprot.writeString(struct.tableName);
        }
        if (struct.isSetIteratorName()) {
          oprot.writeString(struct.iteratorName);
        }
        if (struct.isSetScope()) {
          oprot.writeI32(struct.scope.getValue());
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getIteratorSetting_args struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.tableName = iprot.readString();
          struct.setTableNameIsSet(true);
        }
        if (incoming.get(2)) {
          struct.iteratorName = iprot.readString();
          struct.setIteratorNameIsSet(true);
        }
        if (incoming.get(3)) {
          struct.scope = org.apache.accumulo.proxy.thrift.IteratorScope.findByValue(iprot.readI32());
          struct.setScopeIsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getIteratorSetting_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.STRUCT, (short)0);
    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField OUCH3_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch3", org.apache.thrift.protocol.TType.STRUCT, (short)3);

    private static final 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
    public AccumuloSecurityException ouch2; // required
    public TableNotFoundException ouch3; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      OUCH1((short)1, "ouch1"),
      OUCH2((short)2, "ouch2"),
      OUCH3((short)3, "ouch3");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // OUCH1
            return OUCH1;
          case 2: // OUCH2
            return OUCH2;
          case 3: // OUCH3
            return OUCH3;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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.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.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);
    }

    public getIteratorSetting_result() {
    }

    public getIteratorSetting_result(
      IteratorSetting success,
      AccumuloException ouch1,
      AccumuloSecurityException ouch2,
      TableNotFoundException ouch3)
    {
      this();
      this.success = success;
      this.ouch1 = ouch1;
      this.ouch2 = ouch2;
      this.ouch3 = ouch3;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getIteratorSetting_result(getIteratorSetting_result other) {
      if (other.isSetSuccess()) {
        this.success = new IteratorSetting(other.success);
      }
      if (other.isSetOuch1()) {
        this.ouch1 = new AccumuloException(other.ouch1);
      }
      if (other.isSetOuch2()) {
        this.ouch2 = new AccumuloSecurityException(other.ouch2);
      }
      if (other.isSetOuch3()) {
        this.ouch3 = new TableNotFoundException(other.ouch3);
      }
    }

    public getIteratorSetting_result deepCopy() {
      return new getIteratorSetting_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ouch1 = null;
      this.ouch2 = null;
      this.ouch3 = null;
    }

    public IteratorSetting getSuccess() {
      return this.success;
    }

    public getIteratorSetting_result setSuccess(IteratorSetting success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return this.success != null;
    }

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public AccumuloException getOuch1() {
      return this.ouch1;
    }

    public getIteratorSetting_result setOuch1(AccumuloException ouch1) {
      this.ouch1 = ouch1;
      return this;
    }

    public void unsetOuch1() {
      this.ouch1 = null;
    }

    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch1() {
      return this.ouch1 != null;
    }

    public void setOuch1IsSet(boolean value) {
      if (!value) {
        this.ouch1 = null;
      }
    }

    public AccumuloSecurityException getOuch2() {
      return this.ouch2;
    }

    public getIteratorSetting_result setOuch2(AccumuloSecurityException ouch2) {
      this.ouch2 = ouch2;
      return this;
    }

    public void unsetOuch2() {
      this.ouch2 = null;
    }

    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch2() {
      return this.ouch2 != null;
    }

    public void setOuch2IsSet(boolean value) {
      if (!value) {
        this.ouch2 = null;
      }
    }

    public TableNotFoundException getOuch3() {
      return this.ouch3;
    }

    public getIteratorSetting_result setOuch3(TableNotFoundException ouch3) {
      this.ouch3 = ouch3;
      return this;
    }

    public void unsetOuch3() {
      this.ouch3 = null;
    }

    /** Returns true if field ouch3 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch3() {
      return this.ouch3 != null;
    }

    public void setOuch3IsSet(boolean value) {
      if (!value) {
        this.ouch3 = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((IteratorSetting)value);
        }
        break;

      case OUCH1:
        if (value == null) {
          unsetOuch1();
        } else {
          setOuch1((AccumuloException)value);
        }
        break;

      case OUCH2:
        if (value == null) {
          unsetOuch2();
        } else {
          setOuch2((AccumuloSecurityException)value);
        }
        break;

      case OUCH3:
        if (value == null) {
          unsetOuch3();
        } else {
          setOuch3((TableNotFoundException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case OUCH1:
        return getOuch1();

      case OUCH2:
        return getOuch2();

      case OUCH3:
        return getOuch3();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case OUCH1:
        return isSetOuch1();
      case OUCH2:
        return isSetOuch2();
      case OUCH3:
        return isSetOuch3();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof getIteratorSetting_result)
        return this.equals((getIteratorSetting_result)that);
      return false;
    }

    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();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ouch1 = true && this.isSetOuch1();
      boolean that_present_ouch1 = true && that.isSetOuch1();
      if (this_present_ouch1 || that_present_ouch1) {
        if (!(this_present_ouch1 && that_present_ouch1))
          return false;
        if (!this.ouch1.equals(that.ouch1))
          return false;
      }

      boolean this_present_ouch2 = true && this.isSetOuch2();
      boolean that_present_ouch2 = true && that.isSetOuch2();
      if (this_present_ouch2 || that_present_ouch2) {
        if (!(this_present_ouch2 && that_present_ouch2))
          return false;
        if (!this.ouch2.equals(that.ouch2))
          return false;
      }

      boolean this_present_ouch3 = true && this.isSetOuch3();
      boolean that_present_ouch3 = true && that.isSetOuch3();
      if (this_present_ouch3 || that_present_ouch3) {
        if (!(this_present_ouch3 && that_present_ouch3))
          return false;
        if (!this.ouch3.equals(that.ouch3))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
      if (isSetSuccess())
        hashCode = hashCode * 8191 + success.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
      if (isSetOuch1())
        hashCode = hashCode * 8191 + ouch1.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
      if (isSetOuch2())
        hashCode = hashCode * 8191 + ouch2.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
      if (isSetOuch3())
        hashCode = hashCode * 8191 + ouch3.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(getIteratorSetting_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch1()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch2()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch3()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch3, other.ouch3);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("getIteratorSetting_result(");
      boolean first = true;

      sb.append("success:");
      if (this.success == null) {
        sb.append("null");
      } else {
        sb.append(this.success);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch1:");
      if (this.ouch1 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch1);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch2:");
      if (this.ouch2 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch2);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch3:");
      if (this.ouch3 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch3);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
      if (success != null) {
        success.validate();
      }
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class getIteratorSetting_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getIteratorSetting_resultStandardScheme getScheme() {
        return new getIteratorSetting_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.success = new IteratorSetting();
                struct.success.read(iprot);
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // OUCH1
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch1 = new AccumuloException();
                struct.ouch1.read(iprot);
                struct.setOuch1IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OUCH2
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch2 = new AccumuloSecurityException();
                struct.ouch2.read(iprot);
                struct.setOuch2IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // OUCH3
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch3 = new TableNotFoundException();
                struct.ouch3.read(iprot);
                struct.setOuch3IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getIteratorSetting_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          struct.success.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch1 != null) {
          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
          struct.ouch1.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch2 != null) {
          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
          struct.ouch2.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch3 != null) {
          oprot.writeFieldBegin(OUCH3_FIELD_DESC);
          struct.ouch3.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getIteratorSetting_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getIteratorSetting_resultTupleScheme getScheme() {
        return new getIteratorSetting_resultTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetOuch1()) {
          optionals.set(1);
        }
        if (struct.isSetOuch2()) {
          optionals.set(2);
        }
        if (struct.isSetOuch3()) {
          optionals.set(3);
        }
        oprot.writeBitSet(optionals, 4);
        if (struct.isSetSuccess()) {
          struct.success.write(oprot);
        }
        if (struct.isSetOuch1()) {
          struct.ouch1.write(oprot);
        }
        if (struct.isSetOuch2()) {
          struct.ouch2.write(oprot);
        }
        if (struct.isSetOuch3()) {
          struct.ouch3.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getIteratorSetting_result struct) throws org.apache.thrift.TException {
        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);
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ouch1 = new AccumuloException();
          struct.ouch1.read(iprot);
          struct.setOuch1IsSet(true);
        }
        if (incoming.get(2)) {
          struct.ouch2 = new AccumuloSecurityException();
          struct.ouch2.read(iprot);
          struct.setOuch2IsSet(true);
        }
        if (incoming.get(3)) {
          struct.ouch3 = new TableNotFoundException();
          struct.ouch3.read(iprot);
          struct.setOuch3IsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getMaxRow_args");

    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField 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 AUTHS_FIELD_DESC = new org.apache.thrift.protocol.TField("auths", org.apache.thrift.protocol.TType.SET, (short)3);
    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)4);
    private static final org.apache.thrift.protocol.TField START_INCLUSIVE_FIELD_DESC = new org.apache.thrift.protocol.TField("startInclusive", org.apache.thrift.protocol.TType.BOOL, (short)5);
    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 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 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 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. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      LOGIN((short)1, "login"),
      TABLE_NAME((short)2, "tableName"),
      AUTHS((short)3, "auths"),
      START_ROW((short)4, "startRow"),
      START_INCLUSIVE((short)5, "startInclusive"),
      END_ROW((short)6, "endRow"),
      END_INCLUSIVE((short)7, "endInclusive");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // LOGIN
            return LOGIN;
          case 2: // TABLE_NAME
            return TABLE_NAME;
          case 3: // AUTHS
            return AUTHS;
          case 4: // START_ROW
            return START_ROW;
          case 5: // START_INCLUSIVE
            return START_INCLUSIVE;
          case 6: // END_ROW
            return END_ROW;
          case 7: // END_INCLUSIVE
            return END_INCLUSIVE;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __STARTINCLUSIVE_ISSET_ID = 0;
    private static final int __ENDINCLUSIVE_ISSET_ID = 1;
    private byte __isset_bitfield = 0;
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.AUTHS, new org.apache.thrift.meta_data.FieldMetaData("auths", 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))));
      tmpMap.put(_Fields.START_ROW, new org.apache.thrift.meta_data.FieldMetaData("startRow", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING          , true)));
      tmpMap.put(_Fields.START_INCLUSIVE, new org.apache.thrift.meta_data.FieldMetaData("startInclusive", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
      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.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 = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getMaxRow_args.class, metaDataMap);
    }

    public getMaxRow_args() {
    }

    public getMaxRow_args(
      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)
    {
      this();
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      this.tableName = tableName;
      this.auths = auths;
      this.startRow = org.apache.thrift.TBaseHelper.copyBinary(startRow);
      this.startInclusive = startInclusive;
      setStartInclusiveIsSet(true);
      this.endRow = org.apache.thrift.TBaseHelper.copyBinary(endRow);
      this.endInclusive = endInclusive;
      setEndInclusiveIsSet(true);
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getMaxRow_args(getMaxRow_args other) {
      __isset_bitfield = other.__isset_bitfield;
      if (other.isSetLogin()) {
        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
      }
      if (other.isSetTableName()) {
        this.tableName = other.tableName;
      }
      if (other.isSetAuths()) {
        java.util.Set<java.nio.ByteBuffer> __this__auths = new java.util.HashSet<java.nio.ByteBuffer>(other.auths);
        this.auths = __this__auths;
      }
      if (other.isSetStartRow()) {
        this.startRow = org.apache.thrift.TBaseHelper.copyBinary(other.startRow);
      }
      this.startInclusive = other.startInclusive;
      if (other.isSetEndRow()) {
        this.endRow = org.apache.thrift.TBaseHelper.copyBinary(other.endRow);
      }
      this.endInclusive = other.endInclusive;
    }

    public getMaxRow_args deepCopy() {
      return new getMaxRow_args(this);
    }

    @Override
    public void clear() {
      this.login = null;
      this.tableName = null;
      this.auths = null;
      this.startRow = null;
      setStartInclusiveIsSet(false);
      this.startInclusive = false;
      this.endRow = null;
      setEndInclusiveIsSet(false);
      this.endInclusive = false;
    }

    public byte[] getLogin() {
      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
      return login == null ? null : login.array();
    }

    public java.nio.ByteBuffer bufferForLogin() {
      return org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    public getMaxRow_args setLogin(byte[] login) {
      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
      return this;
    }

    public getMaxRow_args setLogin(java.nio.ByteBuffer login) {
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      return this;
    }

    public void unsetLogin() {
      this.login = null;
    }

    /** Returns true if field login is set (has been assigned a value) and false otherwise */
    public boolean isSetLogin() {
      return this.login != null;
    }

    public void setLoginIsSet(boolean value) {
      if (!value) {
        this.login = null;
      }
    }

    public java.lang.String getTableName() {
      return this.tableName;
    }

    public getMaxRow_args setTableName(java.lang.String tableName) {
      this.tableName = tableName;
      return this;
    }

    public void unsetTableName() {
      this.tableName = null;
    }

    /** Returns true if field tableName is set (has been assigned a value) and false otherwise */
    public boolean isSetTableName() {
      return this.tableName != null;
    }

    public void setTableNameIsSet(boolean value) {
      if (!value) {
        this.tableName = null;
      }
    }

    public int getAuthsSize() {
      return (this.auths == null) ? 0 : this.auths.size();
    }

    public java.util.Iterator<java.nio.ByteBuffer> getAuthsIterator() {
      return (this.auths == null) ? null : this.auths.iterator();
    }

    public void addToAuths(java.nio.ByteBuffer elem) {
      if (this.auths == null) {
        this.auths = new java.util.HashSet<java.nio.ByteBuffer>();
      }
      this.auths.add(elem);
    }

    public java.util.Set<java.nio.ByteBuffer> getAuths() {
      return this.auths;
    }

    public getMaxRow_args setAuths(java.util.Set<java.nio.ByteBuffer> auths) {
      this.auths = auths;
      return this;
    }

    public void unsetAuths() {
      this.auths = null;
    }

    /** Returns true if field auths is set (has been assigned a value) and false otherwise */
    public boolean isSetAuths() {
      return this.auths != null;
    }

    public void setAuthsIsSet(boolean value) {
      if (!value) {
        this.auths = null;
      }
    }

    public byte[] getStartRow() {
      setStartRow(org.apache.thrift.TBaseHelper.rightSize(startRow));
      return startRow == null ? null : startRow.array();
    }

    public java.nio.ByteBuffer bufferForStartRow() {
      return org.apache.thrift.TBaseHelper.copyBinary(startRow);
    }

    public getMaxRow_args setStartRow(byte[] startRow) {
      this.startRow = startRow == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(startRow.clone());
      return this;
    }

    public getMaxRow_args setStartRow(java.nio.ByteBuffer startRow) {
      this.startRow = org.apache.thrift.TBaseHelper.copyBinary(startRow);
      return this;
    }

    public void unsetStartRow() {
      this.startRow = null;
    }

    /** Returns true if field startRow is set (has been assigned a value) and false otherwise */
    public boolean isSetStartRow() {
      return this.startRow != null;
    }

    public void setStartRowIsSet(boolean value) {
      if (!value) {
        this.startRow = null;
      }
    }

    public boolean isStartInclusive() {
      return this.startInclusive;
    }

    public getMaxRow_args setStartInclusive(boolean startInclusive) {
      this.startInclusive = startInclusive;
      setStartInclusiveIsSet(true);
      return this;
    }

    public void unsetStartInclusive() {
      __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 org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __STARTINCLUSIVE_ISSET_ID);
    }

    public void setStartInclusiveIsSet(boolean value) {
      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __STARTINCLUSIVE_ISSET_ID, value);
    }

    public byte[] getEndRow() {
      setEndRow(org.apache.thrift.TBaseHelper.rightSize(endRow));
      return endRow == null ? null : endRow.array();
    }

    public java.nio.ByteBuffer bufferForEndRow() {
      return org.apache.thrift.TBaseHelper.copyBinary(endRow);
    }

    public getMaxRow_args setEndRow(byte[] endRow) {
      this.endRow = endRow == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(endRow.clone());
      return this;
    }

    public getMaxRow_args setEndRow(java.nio.ByteBuffer endRow) {
      this.endRow = org.apache.thrift.TBaseHelper.copyBinary(endRow);
      return this;
    }

    public void unsetEndRow() {
      this.endRow = null;
    }

    /** Returns true if field endRow is set (has been assigned a value) and false otherwise */
    public boolean isSetEndRow() {
      return this.endRow != null;
    }

    public void setEndRowIsSet(boolean value) {
      if (!value) {
        this.endRow = null;
      }
    }

    public boolean isEndInclusive() {
      return this.endInclusive;
    }

    public getMaxRow_args setEndInclusive(boolean endInclusive) {
      this.endInclusive = endInclusive;
      setEndInclusiveIsSet(true);
      return this;
    }

    public void unsetEndInclusive() {
      __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 org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __ENDINCLUSIVE_ISSET_ID);
    }

    public void setEndInclusiveIsSet(boolean value) {
      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __ENDINCLUSIVE_ISSET_ID, value);
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case LOGIN:
        if (value == null) {
          unsetLogin();
        } else {
          if (value instanceof byte[]) {
            setLogin((byte[])value);
          } else {
            setLogin((java.nio.ByteBuffer)value);
          }
        }
        break;

      case TABLE_NAME:
        if (value == null) {
          unsetTableName();
        } else {
          setTableName((java.lang.String)value);
        }
        break;

      case AUTHS:
        if (value == null) {
          unsetAuths();
        } else {
          setAuths((java.util.Set<java.nio.ByteBuffer>)value);
        }
        break;

      case START_ROW:
        if (value == null) {
          unsetStartRow();
        } else {
          if (value instanceof byte[]) {
            setStartRow((byte[])value);
          } else {
            setStartRow((java.nio.ByteBuffer)value);
          }
        }
        break;

      case START_INCLUSIVE:
        if (value == null) {
          unsetStartInclusive();
        } else {
          setStartInclusive((java.lang.Boolean)value);
        }
        break;

      case END_ROW:
        if (value == null) {
          unsetEndRow();
        } else {
          if (value instanceof byte[]) {
            setEndRow((byte[])value);
          } else {
            setEndRow((java.nio.ByteBuffer)value);
          }
        }
        break;

      case END_INCLUSIVE:
        if (value == null) {
          unsetEndInclusive();
        } else {
          setEndInclusive((java.lang.Boolean)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case LOGIN:
        return getLogin();

      case TABLE_NAME:
        return getTableName();

      case AUTHS:
        return getAuths();

      case START_ROW:
        return getStartRow();

      case START_INCLUSIVE:
        return isStartInclusive();

      case END_ROW:
        return getEndRow();

      case END_INCLUSIVE:
        return isEndInclusive();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case LOGIN:
        return isSetLogin();
      case TABLE_NAME:
        return isSetTableName();
      case AUTHS:
        return isSetAuths();
      case START_ROW:
        return isSetStartRow();
      case START_INCLUSIVE:
        return isSetStartInclusive();
      case END_ROW:
        return isSetEndRow();
      case END_INCLUSIVE:
        return isSetEndInclusive();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof getMaxRow_args)
        return this.equals((getMaxRow_args)that);
      return false;
    }

    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();
      if (this_present_login || that_present_login) {
        if (!(this_present_login && that_present_login))
          return false;
        if (!this.login.equals(that.login))
          return false;
      }

      boolean this_present_tableName = true && this.isSetTableName();
      boolean that_present_tableName = true && that.isSetTableName();
      if (this_present_tableName || that_present_tableName) {
        if (!(this_present_tableName && that_present_tableName))
          return false;
        if (!this.tableName.equals(that.tableName))
          return false;
      }

      boolean this_present_auths = true && this.isSetAuths();
      boolean that_present_auths = true && that.isSetAuths();
      if (this_present_auths || that_present_auths) {
        if (!(this_present_auths && that_present_auths))
          return false;
        if (!this.auths.equals(that.auths))
          return false;
      }

      boolean this_present_startRow = true && this.isSetStartRow();
      boolean that_present_startRow = true && that.isSetStartRow();
      if (this_present_startRow || that_present_startRow) {
        if (!(this_present_startRow && that_present_startRow))
          return false;
        if (!this.startRow.equals(that.startRow))
          return false;
      }

      boolean this_present_startInclusive = true;
      boolean that_present_startInclusive = true;
      if (this_present_startInclusive || that_present_startInclusive) {
        if (!(this_present_startInclusive && that_present_startInclusive))
          return false;
        if (this.startInclusive != that.startInclusive)
          return false;
      }

      boolean this_present_endRow = true && this.isSetEndRow();
      boolean that_present_endRow = true && that.isSetEndRow();
      if (this_present_endRow || that_present_endRow) {
        if (!(this_present_endRow && that_present_endRow))
          return false;
        if (!this.endRow.equals(that.endRow))
          return false;
      }

      boolean this_present_endInclusive = true;
      boolean that_present_endInclusive = true;
      if (this_present_endInclusive || that_present_endInclusive) {
        if (!(this_present_endInclusive && that_present_endInclusive))
          return false;
        if (this.endInclusive != that.endInclusive)
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
      if (isSetLogin())
        hashCode = hashCode * 8191 + login.hashCode();

      hashCode = hashCode * 8191 + ((isSetTableName()) ? 131071 : 524287);
      if (isSetTableName())
        hashCode = hashCode * 8191 + tableName.hashCode();

      hashCode = hashCode * 8191 + ((isSetAuths()) ? 131071 : 524287);
      if (isSetAuths())
        hashCode = hashCode * 8191 + auths.hashCode();

      hashCode = hashCode * 8191 + ((isSetStartRow()) ? 131071 : 524287);
      if (isSetStartRow())
        hashCode = hashCode * 8191 + startRow.hashCode();

      hashCode = hashCode * 8191 + ((startInclusive) ? 131071 : 524287);

      hashCode = hashCode * 8191 + ((isSetEndRow()) ? 131071 : 524287);
      if (isSetEndRow())
        hashCode = hashCode * 8191 + endRow.hashCode();

      hashCode = hashCode * 8191 + ((endInclusive) ? 131071 : 524287);

      return hashCode;
    }

    @Override
    public int compareTo(getMaxRow_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLogin()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetTableName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.tableName, other.tableName);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetAuths()).compareTo(other.isSetAuths());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAuths()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.auths, other.auths);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetStartRow()).compareTo(other.isSetStartRow());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetStartRow()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.startRow, other.startRow);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetStartInclusive()).compareTo(other.isSetStartInclusive());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetStartInclusive()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.startInclusive, other.startInclusive);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetEndRow()).compareTo(other.isSetEndRow());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetEndRow()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.endRow, other.endRow);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetEndInclusive()).compareTo(other.isSetEndInclusive());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetEndInclusive()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.endInclusive, other.endInclusive);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("getMaxRow_args(");
      boolean first = true;

      sb.append("login:");
      if (this.login == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.login, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("tableName:");
      if (this.tableName == null) {
        sb.append("null");
      } else {
        sb.append(this.tableName);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("auths:");
      if (this.auths == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.auths, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("startRow:");
      if (this.startRow == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.startRow, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("startInclusive:");
      sb.append(this.startInclusive);
      first = false;
      if (!first) sb.append(", ");
      sb.append("endRow:");
      if (this.endRow == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.endRow, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("endInclusive:");
      sb.append(this.endInclusive);
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, 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;
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class getMaxRow_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getMaxRow_argsStandardScheme getScheme() {
        return new getMaxRow_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // LOGIN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.login = iprot.readBinary();
                struct.setLoginIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // TABLE_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.tableName = iprot.readString();
                struct.setTableNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // AUTHS
              if (schemeField.type == org.apache.thrift.protocol.TType.SET) {
                {
                  org.apache.thrift.protocol.TSet _set258 = iprot.readSetBegin();
                  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();
                    struct.auths.add(_elem259);
                  }
                  iprot.readSetEnd();
                }
                struct.setAuthsIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // START_ROW
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.startRow = iprot.readBinary();
                struct.setStartRowIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 5: // START_INCLUSIVE
              if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
                struct.startInclusive = iprot.readBool();
                struct.setStartInclusiveIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 6: // END_ROW
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.endRow = iprot.readBinary();
                struct.setEndRowIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 7: // END_INCLUSIVE
              if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
                struct.endInclusive = iprot.readBool();
                struct.setEndInclusiveIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getMaxRow_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.login != null) {
          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
          oprot.writeBinary(struct.login);
          oprot.writeFieldEnd();
        }
        if (struct.tableName != null) {
          oprot.writeFieldBegin(TABLE_NAME_FIELD_DESC);
          oprot.writeString(struct.tableName);
          oprot.writeFieldEnd();
        }
        if (struct.auths != null) {
          oprot.writeFieldBegin(AUTHS_FIELD_DESC);
          {
            oprot.writeSetBegin(new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRING, struct.auths.size()));
            for (java.nio.ByteBuffer _iter261 : struct.auths)
            {
              oprot.writeBinary(_iter261);
            }
            oprot.writeSetEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.startRow != null) {
          oprot.writeFieldBegin(START_ROW_FIELD_DESC);
          oprot.writeBinary(struct.startRow);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldBegin(START_INCLUSIVE_FIELD_DESC);
        oprot.writeBool(struct.startInclusive);
        oprot.writeFieldEnd();
        if (struct.endRow != null) {
          oprot.writeFieldBegin(END_ROW_FIELD_DESC);
          oprot.writeBinary(struct.endRow);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldBegin(END_INCLUSIVE_FIELD_DESC);
        oprot.writeBool(struct.endInclusive);
        oprot.writeFieldEnd();
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    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 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 {
        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);
        }
        if (struct.isSetTableName()) {
          optionals.set(1);
        }
        if (struct.isSetAuths()) {
          optionals.set(2);
        }
        if (struct.isSetStartRow()) {
          optionals.set(3);
        }
        if (struct.isSetStartInclusive()) {
          optionals.set(4);
        }
        if (struct.isSetEndRow()) {
          optionals.set(5);
        }
        if (struct.isSetEndInclusive()) {
          optionals.set(6);
        }
        oprot.writeBitSet(optionals, 7);
        if (struct.isSetLogin()) {
          oprot.writeBinary(struct.login);
        }
        if (struct.isSetTableName()) {
          oprot.writeString(struct.tableName);
        }
        if (struct.isSetAuths()) {
          {
            oprot.writeI32(struct.auths.size());
            for (java.nio.ByteBuffer _iter262 : struct.auths)
            {
              oprot.writeBinary(_iter262);
            }
          }
        }
        if (struct.isSetStartRow()) {
          oprot.writeBinary(struct.startRow);
        }
        if (struct.isSetStartInclusive()) {
          oprot.writeBool(struct.startInclusive);
        }
        if (struct.isSetEndRow()) {
          oprot.writeBinary(struct.endRow);
        }
        if (struct.isSetEndInclusive()) {
          oprot.writeBool(struct.endInclusive);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getMaxRow_args struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.tableName = iprot.readString();
          struct.setTableNameIsSet(true);
        }
        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 java.util.HashSet<java.nio.ByteBuffer>(2*_set263.size);
            java.nio.ByteBuffer _elem264;
            for (int _i265 = 0; _i265 < _set263.size; ++_i265)
            {
              _elem264 = iprot.readBinary();
              struct.auths.add(_elem264);
            }
          }
          struct.setAuthsIsSet(true);
        }
        if (incoming.get(3)) {
          struct.startRow = iprot.readBinary();
          struct.setStartRowIsSet(true);
        }
        if (incoming.get(4)) {
          struct.startInclusive = iprot.readBool();
          struct.setStartInclusiveIsSet(true);
        }
        if (incoming.get(5)) {
          struct.endRow = iprot.readBinary();
          struct.setEndRowIsSet(true);
        }
        if (incoming.get(6)) {
          struct.endInclusive = iprot.readBool();
          struct.setEndInclusiveIsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getMaxRow_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.STRING, (short)0);
    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField OUCH3_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch3", org.apache.thrift.protocol.TType.STRUCT, (short)3);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new getMaxRow_resultStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new getMaxRow_resultTupleSchemeFactory();

    public java.nio.ByteBuffer success; // required
    public AccumuloException ouch1; // required
    public AccumuloSecurityException ouch2; // required
    public TableNotFoundException ouch3; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      OUCH1((short)1, "ouch1"),
      OUCH2((short)2, "ouch2"),
      OUCH3((short)3, "ouch3");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // OUCH1
            return OUCH1;
          case 2: // OUCH2
            return OUCH2;
          case 3: // OUCH3
            return OUCH3;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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.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.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);
    }

    public getMaxRow_result() {
    }

    public getMaxRow_result(
      java.nio.ByteBuffer success,
      AccumuloException ouch1,
      AccumuloSecurityException ouch2,
      TableNotFoundException ouch3)
    {
      this();
      this.success = org.apache.thrift.TBaseHelper.copyBinary(success);
      this.ouch1 = ouch1;
      this.ouch2 = ouch2;
      this.ouch3 = ouch3;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getMaxRow_result(getMaxRow_result other) {
      if (other.isSetSuccess()) {
        this.success = org.apache.thrift.TBaseHelper.copyBinary(other.success);
      }
      if (other.isSetOuch1()) {
        this.ouch1 = new AccumuloException(other.ouch1);
      }
      if (other.isSetOuch2()) {
        this.ouch2 = new AccumuloSecurityException(other.ouch2);
      }
      if (other.isSetOuch3()) {
        this.ouch3 = new TableNotFoundException(other.ouch3);
      }
    }

    public getMaxRow_result deepCopy() {
      return new getMaxRow_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ouch1 = null;
      this.ouch2 = null;
      this.ouch3 = null;
    }

    public byte[] getSuccess() {
      setSuccess(org.apache.thrift.TBaseHelper.rightSize(success));
      return success == null ? null : success.array();
    }

    public java.nio.ByteBuffer bufferForSuccess() {
      return org.apache.thrift.TBaseHelper.copyBinary(success);
    }

    public getMaxRow_result setSuccess(byte[] success) {
      this.success = success == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(success.clone());
      return this;
    }

    public getMaxRow_result setSuccess(java.nio.ByteBuffer success) {
      this.success = org.apache.thrift.TBaseHelper.copyBinary(success);
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return this.success != null;
    }

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public AccumuloException getOuch1() {
      return this.ouch1;
    }

    public getMaxRow_result setOuch1(AccumuloException ouch1) {
      this.ouch1 = ouch1;
      return this;
    }

    public void unsetOuch1() {
      this.ouch1 = null;
    }

    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch1() {
      return this.ouch1 != null;
    }

    public void setOuch1IsSet(boolean value) {
      if (!value) {
        this.ouch1 = null;
      }
    }

    public AccumuloSecurityException getOuch2() {
      return this.ouch2;
    }

    public getMaxRow_result setOuch2(AccumuloSecurityException ouch2) {
      this.ouch2 = ouch2;
      return this;
    }

    public void unsetOuch2() {
      this.ouch2 = null;
    }

    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch2() {
      return this.ouch2 != null;
    }

    public void setOuch2IsSet(boolean value) {
      if (!value) {
        this.ouch2 = null;
      }
    }

    public TableNotFoundException getOuch3() {
      return this.ouch3;
    }

    public getMaxRow_result setOuch3(TableNotFoundException ouch3) {
      this.ouch3 = ouch3;
      return this;
    }

    public void unsetOuch3() {
      this.ouch3 = null;
    }

    /** Returns true if field ouch3 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch3() {
      return this.ouch3 != null;
    }

    public void setOuch3IsSet(boolean value) {
      if (!value) {
        this.ouch3 = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          if (value instanceof byte[]) {
            setSuccess((byte[])value);
          } else {
            setSuccess((java.nio.ByteBuffer)value);
          }
        }
        break;

      case OUCH1:
        if (value == null) {
          unsetOuch1();
        } else {
          setOuch1((AccumuloException)value);
        }
        break;

      case OUCH2:
        if (value == null) {
          unsetOuch2();
        } else {
          setOuch2((AccumuloSecurityException)value);
        }
        break;

      case OUCH3:
        if (value == null) {
          unsetOuch3();
        } else {
          setOuch3((TableNotFoundException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case OUCH1:
        return getOuch1();

      case OUCH2:
        return getOuch2();

      case OUCH3:
        return getOuch3();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case OUCH1:
        return isSetOuch1();
      case OUCH2:
        return isSetOuch2();
      case OUCH3:
        return isSetOuch3();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof getMaxRow_result)
        return this.equals((getMaxRow_result)that);
      return false;
    }

    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();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ouch1 = true && this.isSetOuch1();
      boolean that_present_ouch1 = true && that.isSetOuch1();
      if (this_present_ouch1 || that_present_ouch1) {
        if (!(this_present_ouch1 && that_present_ouch1))
          return false;
        if (!this.ouch1.equals(that.ouch1))
          return false;
      }

      boolean this_present_ouch2 = true && this.isSetOuch2();
      boolean that_present_ouch2 = true && that.isSetOuch2();
      if (this_present_ouch2 || that_present_ouch2) {
        if (!(this_present_ouch2 && that_present_ouch2))
          return false;
        if (!this.ouch2.equals(that.ouch2))
          return false;
      }

      boolean this_present_ouch3 = true && this.isSetOuch3();
      boolean that_present_ouch3 = true && that.isSetOuch3();
      if (this_present_ouch3 || that_present_ouch3) {
        if (!(this_present_ouch3 && that_present_ouch3))
          return false;
        if (!this.ouch3.equals(that.ouch3))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
      if (isSetSuccess())
        hashCode = hashCode * 8191 + success.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
      if (isSetOuch1())
        hashCode = hashCode * 8191 + ouch1.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
      if (isSetOuch2())
        hashCode = hashCode * 8191 + ouch2.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
      if (isSetOuch3())
        hashCode = hashCode * 8191 + ouch3.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(getMaxRow_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch1()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch2()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch3()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch3, other.ouch3);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("getMaxRow_result(");
      boolean first = true;

      sb.append("success:");
      if (this.success == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.success, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch1:");
      if (this.ouch1 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch1);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch2:");
      if (this.ouch2 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch2);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch3:");
      if (this.ouch3 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch3);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class getMaxRow_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getMaxRow_resultStandardScheme getScheme() {
        return new getMaxRow_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.success = iprot.readBinary();
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // OUCH1
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch1 = new AccumuloException();
                struct.ouch1.read(iprot);
                struct.setOuch1IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OUCH2
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch2 = new AccumuloSecurityException();
                struct.ouch2.read(iprot);
                struct.setOuch2IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // OUCH3
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch3 = new TableNotFoundException();
                struct.ouch3.read(iprot);
                struct.setOuch3IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getMaxRow_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          oprot.writeBinary(struct.success);
          oprot.writeFieldEnd();
        }
        if (struct.ouch1 != null) {
          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
          struct.ouch1.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch2 != null) {
          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
          struct.ouch2.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch3 != null) {
          oprot.writeFieldBegin(OUCH3_FIELD_DESC);
          struct.ouch3.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getMaxRow_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getMaxRow_resultTupleScheme getScheme() {
        return new getMaxRow_resultTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetOuch1()) {
          optionals.set(1);
        }
        if (struct.isSetOuch2()) {
          optionals.set(2);
        }
        if (struct.isSetOuch3()) {
          optionals.set(3);
        }
        oprot.writeBitSet(optionals, 4);
        if (struct.isSetSuccess()) {
          oprot.writeBinary(struct.success);
        }
        if (struct.isSetOuch1()) {
          struct.ouch1.write(oprot);
        }
        if (struct.isSetOuch2()) {
          struct.ouch2.write(oprot);
        }
        if (struct.isSetOuch3()) {
          struct.ouch3.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getMaxRow_result struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.ouch1 = new AccumuloException();
          struct.ouch1.read(iprot);
          struct.setOuch1IsSet(true);
        }
        if (incoming.get(2)) {
          struct.ouch2 = new AccumuloSecurityException();
          struct.ouch2.read(iprot);
          struct.setOuch2IsSet(true);
        }
        if (incoming.get(3)) {
          struct.ouch3 = new TableNotFoundException();
          struct.ouch3.read(iprot);
          struct.setOuch3IsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getTableProperties_args");

    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField 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.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new getTableProperties_argsStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new getTableProperties_argsTupleSchemeFactory();

    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 java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // LOGIN
            return LOGIN;
          case 2: // TABLE_NAME
            return TABLE_NAME;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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 = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getTableProperties_args.class, metaDataMap);
    }

    public getTableProperties_args() {
    }

    public getTableProperties_args(
      java.nio.ByteBuffer login,
      java.lang.String tableName)
    {
      this();
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      this.tableName = tableName;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getTableProperties_args(getTableProperties_args other) {
      if (other.isSetLogin()) {
        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
      }
      if (other.isSetTableName()) {
        this.tableName = other.tableName;
      }
    }

    public getTableProperties_args deepCopy() {
      return new getTableProperties_args(this);
    }

    @Override
    public void clear() {
      this.login = null;
      this.tableName = null;
    }

    public byte[] getLogin() {
      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
      return login == null ? null : login.array();
    }

    public java.nio.ByteBuffer bufferForLogin() {
      return org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    public getTableProperties_args setLogin(byte[] login) {
      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
      return this;
    }

    public getTableProperties_args setLogin(java.nio.ByteBuffer login) {
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      return this;
    }

    public void unsetLogin() {
      this.login = null;
    }

    /** Returns true if field login is set (has been assigned a value) and false otherwise */
    public boolean isSetLogin() {
      return this.login != null;
    }

    public void setLoginIsSet(boolean value) {
      if (!value) {
        this.login = null;
      }
    }

    public java.lang.String getTableName() {
      return this.tableName;
    }

    public getTableProperties_args setTableName(java.lang.String tableName) {
      this.tableName = tableName;
      return this;
    }

    public void unsetTableName() {
      this.tableName = null;
    }

    /** Returns true if field tableName is set (has been assigned a value) and false otherwise */
    public boolean isSetTableName() {
      return this.tableName != null;
    }

    public void setTableNameIsSet(boolean value) {
      if (!value) {
        this.tableName = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case LOGIN:
        if (value == null) {
          unsetLogin();
        } else {
          if (value instanceof byte[]) {
            setLogin((byte[])value);
          } else {
            setLogin((java.nio.ByteBuffer)value);
          }
        }
        break;

      case TABLE_NAME:
        if (value == null) {
          unsetTableName();
        } else {
          setTableName((java.lang.String)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case LOGIN:
        return getLogin();

      case TABLE_NAME:
        return getTableName();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case LOGIN:
        return isSetLogin();
      case TABLE_NAME:
        return isSetTableName();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof getTableProperties_args)
        return this.equals((getTableProperties_args)that);
      return false;
    }

    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();
      if (this_present_login || that_present_login) {
        if (!(this_present_login && that_present_login))
          return false;
        if (!this.login.equals(that.login))
          return false;
      }

      boolean this_present_tableName = true && this.isSetTableName();
      boolean that_present_tableName = true && that.isSetTableName();
      if (this_present_tableName || that_present_tableName) {
        if (!(this_present_tableName && that_present_tableName))
          return false;
        if (!this.tableName.equals(that.tableName))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
      if (isSetLogin())
        hashCode = hashCode * 8191 + login.hashCode();

      hashCode = hashCode * 8191 + ((isSetTableName()) ? 131071 : 524287);
      if (isSetTableName())
        hashCode = hashCode * 8191 + tableName.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(getTableProperties_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLogin()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetTableName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.tableName, other.tableName);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("getTableProperties_args(");
      boolean first = true;

      sb.append("login:");
      if (this.login == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.login, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("tableName:");
      if (this.tableName == null) {
        sb.append("null");
      } else {
        sb.append(this.tableName);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class getTableProperties_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getTableProperties_argsStandardScheme getScheme() {
        return new getTableProperties_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // LOGIN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.login = iprot.readBinary();
                struct.setLoginIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // TABLE_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.tableName = iprot.readString();
                struct.setTableNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getTableProperties_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.login != null) {
          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
          oprot.writeBinary(struct.login);
          oprot.writeFieldEnd();
        }
        if (struct.tableName != null) {
          oprot.writeFieldBegin(TABLE_NAME_FIELD_DESC);
          oprot.writeString(struct.tableName);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    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 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 {
        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);
        }
        if (struct.isSetTableName()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetLogin()) {
          oprot.writeBinary(struct.login);
        }
        if (struct.isSetTableName()) {
          oprot.writeString(struct.tableName);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getTableProperties_args struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.tableName = iprot.readString();
          struct.setTableNameIsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getTableProperties_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.MAP, (short)0);
    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField OUCH3_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch3", org.apache.thrift.protocol.TType.STRUCT, (short)3);

    private static final 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 java.util.Map<java.lang.String,java.lang.String> success; // required
    public AccumuloException ouch1; // required
    public AccumuloSecurityException ouch2; // required
    public TableNotFoundException ouch3; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      OUCH1((short)1, "ouch1"),
      OUCH2((short)2, "ouch2"),
      OUCH3((short)3, "ouch3");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // OUCH1
            return OUCH1;
          case 2: // OUCH2
            return OUCH2;
          case 3: // OUCH3
            return OUCH3;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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.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.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);
    }

    public getTableProperties_result() {
    }

    public getTableProperties_result(
      java.util.Map<java.lang.String,java.lang.String> success,
      AccumuloException ouch1,
      AccumuloSecurityException ouch2,
      TableNotFoundException ouch3)
    {
      this();
      this.success = success;
      this.ouch1 = ouch1;
      this.ouch2 = ouch2;
      this.ouch3 = ouch3;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getTableProperties_result(getTableProperties_result other) {
      if (other.isSetSuccess()) {
        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()) {
        this.ouch1 = new AccumuloException(other.ouch1);
      }
      if (other.isSetOuch2()) {
        this.ouch2 = new AccumuloSecurityException(other.ouch2);
      }
      if (other.isSetOuch3()) {
        this.ouch3 = new TableNotFoundException(other.ouch3);
      }
    }

    public getTableProperties_result deepCopy() {
      return new getTableProperties_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ouch1 = null;
      this.ouch2 = null;
      this.ouch3 = null;
    }

    public int getSuccessSize() {
      return (this.success == null) ? 0 : this.success.size();
    }

    public void putToSuccess(java.lang.String key, java.lang.String val) {
      if (this.success == null) {
        this.success = new java.util.HashMap<java.lang.String,java.lang.String>();
      }
      this.success.put(key, val);
    }

    public java.util.Map<java.lang.String,java.lang.String> getSuccess() {
      return this.success;
    }

    public getTableProperties_result setSuccess(java.util.Map<java.lang.String,java.lang.String> success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return this.success != null;
    }

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public AccumuloException getOuch1() {
      return this.ouch1;
    }

    public getTableProperties_result setOuch1(AccumuloException ouch1) {
      this.ouch1 = ouch1;
      return this;
    }

    public void unsetOuch1() {
      this.ouch1 = null;
    }

    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch1() {
      return this.ouch1 != null;
    }

    public void setOuch1IsSet(boolean value) {
      if (!value) {
        this.ouch1 = null;
      }
    }

    public AccumuloSecurityException getOuch2() {
      return this.ouch2;
    }

    public getTableProperties_result setOuch2(AccumuloSecurityException ouch2) {
      this.ouch2 = ouch2;
      return this;
    }

    public void unsetOuch2() {
      this.ouch2 = null;
    }

    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch2() {
      return this.ouch2 != null;
    }

    public void setOuch2IsSet(boolean value) {
      if (!value) {
        this.ouch2 = null;
      }
    }

    public TableNotFoundException getOuch3() {
      return this.ouch3;
    }

    public getTableProperties_result setOuch3(TableNotFoundException ouch3) {
      this.ouch3 = ouch3;
      return this;
    }

    public void unsetOuch3() {
      this.ouch3 = null;
    }

    /** Returns true if field ouch3 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch3() {
      return this.ouch3 != null;
    }

    public void setOuch3IsSet(boolean value) {
      if (!value) {
        this.ouch3 = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.util.Map<java.lang.String,java.lang.String>)value);
        }
        break;

      case OUCH1:
        if (value == null) {
          unsetOuch1();
        } else {
          setOuch1((AccumuloException)value);
        }
        break;

      case OUCH2:
        if (value == null) {
          unsetOuch2();
        } else {
          setOuch2((AccumuloSecurityException)value);
        }
        break;

      case OUCH3:
        if (value == null) {
          unsetOuch3();
        } else {
          setOuch3((TableNotFoundException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case OUCH1:
        return getOuch1();

      case OUCH2:
        return getOuch2();

      case OUCH3:
        return getOuch3();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case OUCH1:
        return isSetOuch1();
      case OUCH2:
        return isSetOuch2();
      case OUCH3:
        return isSetOuch3();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof getTableProperties_result)
        return this.equals((getTableProperties_result)that);
      return false;
    }

    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();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ouch1 = true && this.isSetOuch1();
      boolean that_present_ouch1 = true && that.isSetOuch1();
      if (this_present_ouch1 || that_present_ouch1) {
        if (!(this_present_ouch1 && that_present_ouch1))
          return false;
        if (!this.ouch1.equals(that.ouch1))
          return false;
      }

      boolean this_present_ouch2 = true && this.isSetOuch2();
      boolean that_present_ouch2 = true && that.isSetOuch2();
      if (this_present_ouch2 || that_present_ouch2) {
        if (!(this_present_ouch2 && that_present_ouch2))
          return false;
        if (!this.ouch2.equals(that.ouch2))
          return false;
      }

      boolean this_present_ouch3 = true && this.isSetOuch3();
      boolean that_present_ouch3 = true && that.isSetOuch3();
      if (this_present_ouch3 || that_present_ouch3) {
        if (!(this_present_ouch3 && that_present_ouch3))
          return false;
        if (!this.ouch3.equals(that.ouch3))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
      if (isSetSuccess())
        hashCode = hashCode * 8191 + success.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
      if (isSetOuch1())
        hashCode = hashCode * 8191 + ouch1.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
      if (isSetOuch2())
        hashCode = hashCode * 8191 + ouch2.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
      if (isSetOuch3())
        hashCode = hashCode * 8191 + ouch3.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(getTableProperties_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch1()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch2()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch3()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch3, other.ouch3);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("getTableProperties_result(");
      boolean first = true;

      sb.append("success:");
      if (this.success == null) {
        sb.append("null");
      } else {
        sb.append(this.success);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch1:");
      if (this.ouch1 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch1);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch2:");
      if (this.ouch2 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch2);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch3:");
      if (this.ouch3 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch3);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class getTableProperties_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getTableProperties_resultStandardScheme getScheme() {
        return new getTableProperties_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.MAP) {
                {
                  org.apache.thrift.protocol.TMap _map266 = iprot.readMapBegin();
                  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();
                    _val268 = iprot.readString();
                    struct.success.put(_key267, _val268);
                  }
                  iprot.readMapEnd();
                }
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // OUCH1
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch1 = new AccumuloException();
                struct.ouch1.read(iprot);
                struct.setOuch1IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OUCH2
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch2 = new AccumuloSecurityException();
                struct.ouch2.read(iprot);
                struct.setOuch2IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // OUCH3
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch3 = new TableNotFoundException();
                struct.ouch3.read(iprot);
                struct.setOuch3IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getTableProperties_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          {
            oprot.writeMapBegin(new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.STRING, struct.success.size()));
            for (java.util.Map.Entry<java.lang.String, java.lang.String> _iter270 : struct.success.entrySet())
            {
              oprot.writeString(_iter270.getKey());
              oprot.writeString(_iter270.getValue());
            }
            oprot.writeMapEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.ouch1 != null) {
          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
          struct.ouch1.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch2 != null) {
          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
          struct.ouch2.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch3 != null) {
          oprot.writeFieldBegin(OUCH3_FIELD_DESC);
          struct.ouch3.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getTableProperties_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getTableProperties_resultTupleScheme getScheme() {
        return new getTableProperties_resultTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetOuch1()) {
          optionals.set(1);
        }
        if (struct.isSetOuch2()) {
          optionals.set(2);
        }
        if (struct.isSetOuch3()) {
          optionals.set(3);
        }
        oprot.writeBitSet(optionals, 4);
        if (struct.isSetSuccess()) {
          {
            oprot.writeI32(struct.success.size());
            for (java.util.Map.Entry<java.lang.String, java.lang.String> _iter271 : struct.success.entrySet())
            {
              oprot.writeString(_iter271.getKey());
              oprot.writeString(_iter271.getValue());
            }
          }
        }
        if (struct.isSetOuch1()) {
          struct.ouch1.write(oprot);
        }
        if (struct.isSetOuch2()) {
          struct.ouch2.write(oprot);
        }
        if (struct.isSetOuch3()) {
          struct.ouch3.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getTableProperties_result struct) throws org.apache.thrift.TException {
        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 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();
              _val274 = iprot.readString();
              struct.success.put(_key273, _val274);
            }
          }
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ouch1 = new AccumuloException();
          struct.ouch1.read(iprot);
          struct.setOuch1IsSet(true);
        }
        if (incoming.get(2)) {
          struct.ouch2 = new AccumuloSecurityException();
          struct.ouch2.read(iprot);
          struct.setOuch2IsSet(true);
        }
        if (incoming.get(3)) {
          struct.ouch3 = new TableNotFoundException();
          struct.ouch3.read(iprot);
          struct.setOuch3IsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("importDirectory_args");

    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField 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 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 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 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. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      LOGIN((short)1, "login"),
      TABLE_NAME((short)2, "tableName"),
      IMPORT_DIR((short)3, "importDir"),
      FAILURE_DIR((short)4, "failureDir"),
      SET_TIME((short)5, "setTime");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // LOGIN
            return LOGIN;
          case 2: // TABLE_NAME
            return TABLE_NAME;
          case 3: // IMPORT_DIR
            return IMPORT_DIR;
          case 4: // FAILURE_DIR
            return FAILURE_DIR;
          case 5: // SET_TIME
            return SET_TIME;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __SETTIME_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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)));
      tmpMap.put(_Fields.FAILURE_DIR, new org.apache.thrift.meta_data.FieldMetaData("failureDir", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          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 = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(importDirectory_args.class, metaDataMap);
    }

    public importDirectory_args() {
    }

    public importDirectory_args(
      java.nio.ByteBuffer login,
      java.lang.String tableName,
      java.lang.String importDir,
      java.lang.String failureDir,
      boolean setTime)
    {
      this();
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      this.tableName = tableName;
      this.importDir = importDir;
      this.failureDir = failureDir;
      this.setTime = setTime;
      setSetTimeIsSet(true);
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public importDirectory_args(importDirectory_args other) {
      __isset_bitfield = other.__isset_bitfield;
      if (other.isSetLogin()) {
        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
      }
      if (other.isSetTableName()) {
        this.tableName = other.tableName;
      }
      if (other.isSetImportDir()) {
        this.importDir = other.importDir;
      }
      if (other.isSetFailureDir()) {
        this.failureDir = other.failureDir;
      }
      this.setTime = other.setTime;
    }

    public importDirectory_args deepCopy() {
      return new importDirectory_args(this);
    }

    @Override
    public void clear() {
      this.login = null;
      this.tableName = null;
      this.importDir = null;
      this.failureDir = null;
      setSetTimeIsSet(false);
      this.setTime = false;
    }

    public byte[] getLogin() {
      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
      return login == null ? null : login.array();
    }

    public java.nio.ByteBuffer bufferForLogin() {
      return org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    public importDirectory_args setLogin(byte[] login) {
      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
      return this;
    }

    public importDirectory_args setLogin(java.nio.ByteBuffer login) {
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      return this;
    }

    public void unsetLogin() {
      this.login = null;
    }

    /** Returns true if field login is set (has been assigned a value) and false otherwise */
    public boolean isSetLogin() {
      return this.login != null;
    }

    public void setLoginIsSet(boolean value) {
      if (!value) {
        this.login = null;
      }
    }

    public java.lang.String getTableName() {
      return this.tableName;
    }

    public importDirectory_args setTableName(java.lang.String tableName) {
      this.tableName = tableName;
      return this;
    }

    public void unsetTableName() {
      this.tableName = null;
    }

    /** Returns true if field tableName is set (has been assigned a value) and false otherwise */
    public boolean isSetTableName() {
      return this.tableName != null;
    }

    public void setTableNameIsSet(boolean value) {
      if (!value) {
        this.tableName = null;
      }
    }

    public java.lang.String getImportDir() {
      return this.importDir;
    }

    public importDirectory_args setImportDir(java.lang.String importDir) {
      this.importDir = importDir;
      return this;
    }

    public void unsetImportDir() {
      this.importDir = null;
    }

    /** Returns true if field importDir is set (has been assigned a value) and false otherwise */
    public boolean isSetImportDir() {
      return this.importDir != null;
    }

    public void setImportDirIsSet(boolean value) {
      if (!value) {
        this.importDir = null;
      }
    }

    public java.lang.String getFailureDir() {
      return this.failureDir;
    }

    public importDirectory_args setFailureDir(java.lang.String failureDir) {
      this.failureDir = failureDir;
      return this;
    }

    public void unsetFailureDir() {
      this.failureDir = null;
    }

    /** Returns true if field failureDir is set (has been assigned a value) and false otherwise */
    public boolean isSetFailureDir() {
      return this.failureDir != null;
    }

    public void setFailureDirIsSet(boolean value) {
      if (!value) {
        this.failureDir = null;
      }
    }

    public boolean isSetTime() {
      return this.setTime;
    }

    public importDirectory_args setSetTime(boolean setTime) {
      this.setTime = setTime;
      setSetTimeIsSet(true);
      return this;
    }

    public void unsetSetTime() {
      __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 org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __SETTIME_ISSET_ID);
    }

    public void setSetTimeIsSet(boolean value) {
      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __SETTIME_ISSET_ID, value);
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case LOGIN:
        if (value == null) {
          unsetLogin();
        } else {
          if (value instanceof byte[]) {
            setLogin((byte[])value);
          } else {
            setLogin((java.nio.ByteBuffer)value);
          }
        }
        break;

      case TABLE_NAME:
        if (value == null) {
          unsetTableName();
        } else {
          setTableName((java.lang.String)value);
        }
        break;

      case IMPORT_DIR:
        if (value == null) {
          unsetImportDir();
        } else {
          setImportDir((java.lang.String)value);
        }
        break;

      case FAILURE_DIR:
        if (value == null) {
          unsetFailureDir();
        } else {
          setFailureDir((java.lang.String)value);
        }
        break;

      case SET_TIME:
        if (value == null) {
          unsetSetTime();
        } else {
          setSetTime((java.lang.Boolean)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case LOGIN:
        return getLogin();

      case TABLE_NAME:
        return getTableName();

      case IMPORT_DIR:
        return getImportDir();

      case FAILURE_DIR:
        return getFailureDir();

      case SET_TIME:
        return isSetTime();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case LOGIN:
        return isSetLogin();
      case TABLE_NAME:
        return isSetTableName();
      case IMPORT_DIR:
        return isSetImportDir();
      case FAILURE_DIR:
        return isSetFailureDir();
      case SET_TIME:
        return isSetSetTime();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof importDirectory_args)
        return this.equals((importDirectory_args)that);
      return false;
    }

    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();
      if (this_present_login || that_present_login) {
        if (!(this_present_login && that_present_login))
          return false;
        if (!this.login.equals(that.login))
          return false;
      }

      boolean this_present_tableName = true && this.isSetTableName();
      boolean that_present_tableName = true && that.isSetTableName();
      if (this_present_tableName || that_present_tableName) {
        if (!(this_present_tableName && that_present_tableName))
          return false;
        if (!this.tableName.equals(that.tableName))
          return false;
      }

      boolean this_present_importDir = true && this.isSetImportDir();
      boolean that_present_importDir = true && that.isSetImportDir();
      if (this_present_importDir || that_present_importDir) {
        if (!(this_present_importDir && that_present_importDir))
          return false;
        if (!this.importDir.equals(that.importDir))
          return false;
      }

      boolean this_present_failureDir = true && this.isSetFailureDir();
      boolean that_present_failureDir = true && that.isSetFailureDir();
      if (this_present_failureDir || that_present_failureDir) {
        if (!(this_present_failureDir && that_present_failureDir))
          return false;
        if (!this.failureDir.equals(that.failureDir))
          return false;
      }

      boolean this_present_setTime = true;
      boolean that_present_setTime = true;
      if (this_present_setTime || that_present_setTime) {
        if (!(this_present_setTime && that_present_setTime))
          return false;
        if (this.setTime != that.setTime)
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
      if (isSetLogin())
        hashCode = hashCode * 8191 + login.hashCode();

      hashCode = hashCode * 8191 + ((isSetTableName()) ? 131071 : 524287);
      if (isSetTableName())
        hashCode = hashCode * 8191 + tableName.hashCode();

      hashCode = hashCode * 8191 + ((isSetImportDir()) ? 131071 : 524287);
      if (isSetImportDir())
        hashCode = hashCode * 8191 + importDir.hashCode();

      hashCode = hashCode * 8191 + ((isSetFailureDir()) ? 131071 : 524287);
      if (isSetFailureDir())
        hashCode = hashCode * 8191 + failureDir.hashCode();

      hashCode = hashCode * 8191 + ((setTime) ? 131071 : 524287);

      return hashCode;
    }

    @Override
    public int compareTo(importDirectory_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLogin()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetTableName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.tableName, other.tableName);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetImportDir()).compareTo(other.isSetImportDir());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetImportDir()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.importDir, other.importDir);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetFailureDir()).compareTo(other.isSetFailureDir());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetFailureDir()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.failureDir, other.failureDir);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetSetTime()).compareTo(other.isSetSetTime());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSetTime()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.setTime, other.setTime);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("importDirectory_args(");
      boolean first = true;

      sb.append("login:");
      if (this.login == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.login, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("tableName:");
      if (this.tableName == null) {
        sb.append("null");
      } else {
        sb.append(this.tableName);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("importDir:");
      if (this.importDir == null) {
        sb.append("null");
      } else {
        sb.append(this.importDir);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("failureDir:");
      if (this.failureDir == null) {
        sb.append("null");
      } else {
        sb.append(this.failureDir);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("setTime:");
      sb.append(this.setTime);
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, 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;
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class importDirectory_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public importDirectory_argsStandardScheme getScheme() {
        return new importDirectory_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // LOGIN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.login = iprot.readBinary();
                struct.setLoginIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // TABLE_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.tableName = iprot.readString();
                struct.setTableNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // IMPORT_DIR
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.importDir = iprot.readString();
                struct.setImportDirIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // FAILURE_DIR
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.failureDir = iprot.readString();
                struct.setFailureDirIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 5: // SET_TIME
              if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
                struct.setTime = iprot.readBool();
                struct.setSetTimeIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, importDirectory_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.login != null) {
          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
          oprot.writeBinary(struct.login);
          oprot.writeFieldEnd();
        }
        if (struct.tableName != null) {
          oprot.writeFieldBegin(TABLE_NAME_FIELD_DESC);
          oprot.writeString(struct.tableName);
          oprot.writeFieldEnd();
        }
        if (struct.importDir != null) {
          oprot.writeFieldBegin(IMPORT_DIR_FIELD_DESC);
          oprot.writeString(struct.importDir);
          oprot.writeFieldEnd();
        }
        if (struct.failureDir != null) {
          oprot.writeFieldBegin(FAILURE_DIR_FIELD_DESC);
          oprot.writeString(struct.failureDir);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldBegin(SET_TIME_FIELD_DESC);
        oprot.writeBool(struct.setTime);
        oprot.writeFieldEnd();
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    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 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 {
        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);
        }
        if (struct.isSetTableName()) {
          optionals.set(1);
        }
        if (struct.isSetImportDir()) {
          optionals.set(2);
        }
        if (struct.isSetFailureDir()) {
          optionals.set(3);
        }
        if (struct.isSetSetTime()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetLogin()) {
          oprot.writeBinary(struct.login);
        }
        if (struct.isSetTableName()) {
          oprot.writeString(struct.tableName);
        }
        if (struct.isSetImportDir()) {
          oprot.writeString(struct.importDir);
        }
        if (struct.isSetFailureDir()) {
          oprot.writeString(struct.failureDir);
        }
        if (struct.isSetSetTime()) {
          oprot.writeBool(struct.setTime);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, importDirectory_args struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.tableName = iprot.readString();
          struct.setTableNameIsSet(true);
        }
        if (incoming.get(2)) {
          struct.importDir = iprot.readString();
          struct.setImportDirIsSet(true);
        }
        if (incoming.get(3)) {
          struct.failureDir = iprot.readString();
          struct.setFailureDirIsSet(true);
        }
        if (incoming.get(4)) {
          struct.setTime = iprot.readBool();
          struct.setSetTimeIsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("importDirectory_result");

    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField 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 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
    public AccumuloSecurityException ouch4; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      OUCH1((short)1, "ouch1"),
      OUCH3((short)2, "ouch3"),
      OUCH4((short)3, "ouch4");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // OUCH1
            return OUCH1;
          case 2: // OUCH3
            return OUCH3;
          case 3: // OUCH4
            return OUCH4;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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.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.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);
    }

    public importDirectory_result() {
    }

    public importDirectory_result(
      TableNotFoundException ouch1,
      AccumuloException ouch3,
      AccumuloSecurityException ouch4)
    {
      this();
      this.ouch1 = ouch1;
      this.ouch3 = ouch3;
      this.ouch4 = ouch4;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public importDirectory_result(importDirectory_result other) {
      if (other.isSetOuch1()) {
        this.ouch1 = new TableNotFoundException(other.ouch1);
      }
      if (other.isSetOuch3()) {
        this.ouch3 = new AccumuloException(other.ouch3);
      }
      if (other.isSetOuch4()) {
        this.ouch4 = new AccumuloSecurityException(other.ouch4);
      }
    }

    public importDirectory_result deepCopy() {
      return new importDirectory_result(this);
    }

    @Override
    public void clear() {
      this.ouch1 = null;
      this.ouch3 = null;
      this.ouch4 = null;
    }

    public TableNotFoundException getOuch1() {
      return this.ouch1;
    }

    public importDirectory_result setOuch1(TableNotFoundException ouch1) {
      this.ouch1 = ouch1;
      return this;
    }

    public void unsetOuch1() {
      this.ouch1 = null;
    }

    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch1() {
      return this.ouch1 != null;
    }

    public void setOuch1IsSet(boolean value) {
      if (!value) {
        this.ouch1 = null;
      }
    }

    public AccumuloException getOuch3() {
      return this.ouch3;
    }

    public importDirectory_result setOuch3(AccumuloException ouch3) {
      this.ouch3 = ouch3;
      return this;
    }

    public void unsetOuch3() {
      this.ouch3 = null;
    }

    /** Returns true if field ouch3 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch3() {
      return this.ouch3 != null;
    }

    public void setOuch3IsSet(boolean value) {
      if (!value) {
        this.ouch3 = null;
      }
    }

    public AccumuloSecurityException getOuch4() {
      return this.ouch4;
    }

    public importDirectory_result setOuch4(AccumuloSecurityException ouch4) {
      this.ouch4 = ouch4;
      return this;
    }

    public void unsetOuch4() {
      this.ouch4 = null;
    }

    /** Returns true if field ouch4 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch4() {
      return this.ouch4 != null;
    }

    public void setOuch4IsSet(boolean value) {
      if (!value) {
        this.ouch4 = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case OUCH1:
        if (value == null) {
          unsetOuch1();
        } else {
          setOuch1((TableNotFoundException)value);
        }
        break;

      case OUCH3:
        if (value == null) {
          unsetOuch3();
        } else {
          setOuch3((AccumuloException)value);
        }
        break;

      case OUCH4:
        if (value == null) {
          unsetOuch4();
        } else {
          setOuch4((AccumuloSecurityException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case OUCH1:
        return getOuch1();

      case OUCH3:
        return getOuch3();

      case OUCH4:
        return getOuch4();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case OUCH1:
        return isSetOuch1();
      case OUCH3:
        return isSetOuch3();
      case OUCH4:
        return isSetOuch4();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof importDirectory_result)
        return this.equals((importDirectory_result)that);
      return false;
    }

    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();
      if (this_present_ouch1 || that_present_ouch1) {
        if (!(this_present_ouch1 && that_present_ouch1))
          return false;
        if (!this.ouch1.equals(that.ouch1))
          return false;
      }

      boolean this_present_ouch3 = true && this.isSetOuch3();
      boolean that_present_ouch3 = true && that.isSetOuch3();
      if (this_present_ouch3 || that_present_ouch3) {
        if (!(this_present_ouch3 && that_present_ouch3))
          return false;
        if (!this.ouch3.equals(that.ouch3))
          return false;
      }

      boolean this_present_ouch4 = true && this.isSetOuch4();
      boolean that_present_ouch4 = true && that.isSetOuch4();
      if (this_present_ouch4 || that_present_ouch4) {
        if (!(this_present_ouch4 && that_present_ouch4))
          return false;
        if (!this.ouch4.equals(that.ouch4))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
      if (isSetOuch1())
        hashCode = hashCode * 8191 + ouch1.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
      if (isSetOuch3())
        hashCode = hashCode * 8191 + ouch3.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch4()) ? 131071 : 524287);
      if (isSetOuch4())
        hashCode = hashCode * 8191 + ouch4.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(importDirectory_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch1()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch3()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch3, other.ouch3);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch4()).compareTo(other.isSetOuch4());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch4()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch4, other.ouch4);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("importDirectory_result(");
      boolean first = true;

      sb.append("ouch1:");
      if (this.ouch1 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch1);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch3:");
      if (this.ouch3 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch3);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch4:");
      if (this.ouch4 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch4);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class importDirectory_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public importDirectory_resultStandardScheme getScheme() {
        return new importDirectory_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // OUCH1
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch1 = new TableNotFoundException();
                struct.ouch1.read(iprot);
                struct.setOuch1IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OUCH3
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch3 = new AccumuloException();
                struct.ouch3.read(iprot);
                struct.setOuch3IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // OUCH4
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch4 = new AccumuloSecurityException();
                struct.ouch4.read(iprot);
                struct.setOuch4IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, importDirectory_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.ouch1 != null) {
          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
          struct.ouch1.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch3 != null) {
          oprot.writeFieldBegin(OUCH3_FIELD_DESC);
          struct.ouch3.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch4 != null) {
          oprot.writeFieldBegin(OUCH4_FIELD_DESC);
          struct.ouch4.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class importDirectory_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public importDirectory_resultTupleScheme getScheme() {
        return new importDirectory_resultTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetOuch3()) {
          optionals.set(1);
        }
        if (struct.isSetOuch4()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetOuch1()) {
          struct.ouch1.write(oprot);
        }
        if (struct.isSetOuch3()) {
          struct.ouch3.write(oprot);
        }
        if (struct.isSetOuch4()) {
          struct.ouch4.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, importDirectory_result struct) throws org.apache.thrift.TException {
        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);
          struct.setOuch1IsSet(true);
        }
        if (incoming.get(1)) {
          struct.ouch3 = new AccumuloException();
          struct.ouch3.read(iprot);
          struct.setOuch3IsSet(true);
        }
        if (incoming.get(2)) {
          struct.ouch4 = new AccumuloSecurityException();
          struct.ouch4.read(iprot);
          struct.setOuch4IsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("importTable_args");

    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField 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 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 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 {
      LOGIN((short)1, "login"),
      TABLE_NAME((short)2, "tableName"),
      IMPORT_DIR((short)3, "importDir");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // LOGIN
            return LOGIN;
          case 2: // TABLE_NAME
            return TABLE_NAME;
          case 3: // IMPORT_DIR
            return IMPORT_DIR;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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 = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(importTable_args.class, metaDataMap);
    }

    public importTable_args() {
    }

    public importTable_args(
      java.nio.ByteBuffer login,
      java.lang.String tableName,
      java.lang.String importDir)
    {
      this();
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      this.tableName = tableName;
      this.importDir = importDir;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public importTable_args(importTable_args other) {
      if (other.isSetLogin()) {
        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
      }
      if (other.isSetTableName()) {
        this.tableName = other.tableName;
      }
      if (other.isSetImportDir()) {
        this.importDir = other.importDir;
      }
    }

    public importTable_args deepCopy() {
      return new importTable_args(this);
    }

    @Override
    public void clear() {
      this.login = null;
      this.tableName = null;
      this.importDir = null;
    }

    public byte[] getLogin() {
      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
      return login == null ? null : login.array();
    }

    public java.nio.ByteBuffer bufferForLogin() {
      return org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    public importTable_args setLogin(byte[] login) {
      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
      return this;
    }

    public importTable_args setLogin(java.nio.ByteBuffer login) {
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      return this;
    }

    public void unsetLogin() {
      this.login = null;
    }

    /** Returns true if field login is set (has been assigned a value) and false otherwise */
    public boolean isSetLogin() {
      return this.login != null;
    }

    public void setLoginIsSet(boolean value) {
      if (!value) {
        this.login = null;
      }
    }

    public java.lang.String getTableName() {
      return this.tableName;
    }

    public importTable_args setTableName(java.lang.String tableName) {
      this.tableName = tableName;
      return this;
    }

    public void unsetTableName() {
      this.tableName = null;
    }

    /** Returns true if field tableName is set (has been assigned a value) and false otherwise */
    public boolean isSetTableName() {
      return this.tableName != null;
    }

    public void setTableNameIsSet(boolean value) {
      if (!value) {
        this.tableName = null;
      }
    }

    public java.lang.String getImportDir() {
      return this.importDir;
    }

    public importTable_args setImportDir(java.lang.String importDir) {
      this.importDir = importDir;
      return this;
    }

    public void unsetImportDir() {
      this.importDir = null;
    }

    /** Returns true if field importDir is set (has been assigned a value) and false otherwise */
    public boolean isSetImportDir() {
      return this.importDir != null;
    }

    public void setImportDirIsSet(boolean value) {
      if (!value) {
        this.importDir = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case LOGIN:
        if (value == null) {
          unsetLogin();
        } else {
          if (value instanceof byte[]) {
            setLogin((byte[])value);
          } else {
            setLogin((java.nio.ByteBuffer)value);
          }
        }
        break;

      case TABLE_NAME:
        if (value == null) {
          unsetTableName();
        } else {
          setTableName((java.lang.String)value);
        }
        break;

      case IMPORT_DIR:
        if (value == null) {
          unsetImportDir();
        } else {
          setImportDir((java.lang.String)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case LOGIN:
        return getLogin();

      case TABLE_NAME:
        return getTableName();

      case IMPORT_DIR:
        return getImportDir();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case LOGIN:
        return isSetLogin();
      case TABLE_NAME:
        return isSetTableName();
      case IMPORT_DIR:
        return isSetImportDir();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof importTable_args)
        return this.equals((importTable_args)that);
      return false;
    }

    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();
      if (this_present_login || that_present_login) {
        if (!(this_present_login && that_present_login))
          return false;
        if (!this.login.equals(that.login))
          return false;
      }

      boolean this_present_tableName = true && this.isSetTableName();
      boolean that_present_tableName = true && that.isSetTableName();
      if (this_present_tableName || that_present_tableName) {
        if (!(this_present_tableName && that_present_tableName))
          return false;
        if (!this.tableName.equals(that.tableName))
          return false;
      }

      boolean this_present_importDir = true && this.isSetImportDir();
      boolean that_present_importDir = true && that.isSetImportDir();
      if (this_present_importDir || that_present_importDir) {
        if (!(this_present_importDir && that_present_importDir))
          return false;
        if (!this.importDir.equals(that.importDir))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
      if (isSetLogin())
        hashCode = hashCode * 8191 + login.hashCode();

      hashCode = hashCode * 8191 + ((isSetTableName()) ? 131071 : 524287);
      if (isSetTableName())
        hashCode = hashCode * 8191 + tableName.hashCode();

      hashCode = hashCode * 8191 + ((isSetImportDir()) ? 131071 : 524287);
      if (isSetImportDir())
        hashCode = hashCode * 8191 + importDir.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(importTable_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLogin()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetTableName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.tableName, other.tableName);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetImportDir()).compareTo(other.isSetImportDir());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetImportDir()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.importDir, other.importDir);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("importTable_args(");
      boolean first = true;

      sb.append("login:");
      if (this.login == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.login, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("tableName:");
      if (this.tableName == null) {
        sb.append("null");
      } else {
        sb.append(this.tableName);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("importDir:");
      if (this.importDir == null) {
        sb.append("null");
      } else {
        sb.append(this.importDir);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class importTable_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public importTable_argsStandardScheme getScheme() {
        return new importTable_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // LOGIN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.login = iprot.readBinary();
                struct.setLoginIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // TABLE_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.tableName = iprot.readString();
                struct.setTableNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // IMPORT_DIR
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.importDir = iprot.readString();
                struct.setImportDirIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, importTable_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.login != null) {
          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
          oprot.writeBinary(struct.login);
          oprot.writeFieldEnd();
        }
        if (struct.tableName != null) {
          oprot.writeFieldBegin(TABLE_NAME_FIELD_DESC);
          oprot.writeString(struct.tableName);
          oprot.writeFieldEnd();
        }
        if (struct.importDir != null) {
          oprot.writeFieldBegin(IMPORT_DIR_FIELD_DESC);
          oprot.writeString(struct.importDir);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    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 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 {
        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);
        }
        if (struct.isSetTableName()) {
          optionals.set(1);
        }
        if (struct.isSetImportDir()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetLogin()) {
          oprot.writeBinary(struct.login);
        }
        if (struct.isSetTableName()) {
          oprot.writeString(struct.tableName);
        }
        if (struct.isSetImportDir()) {
          oprot.writeString(struct.importDir);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, importTable_args struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.tableName = iprot.readString();
          struct.setTableNameIsSet(true);
        }
        if (incoming.get(2)) {
          struct.importDir = iprot.readString();
          struct.setImportDirIsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("importTable_result");

    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField OUCH3_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch3", org.apache.thrift.protocol.TType.STRUCT, (short)3);

    private static final org.apache.thrift.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
    public AccumuloSecurityException ouch3; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      OUCH1((short)1, "ouch1"),
      OUCH2((short)2, "ouch2"),
      OUCH3((short)3, "ouch3");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // OUCH1
            return OUCH1;
          case 2: // OUCH2
            return OUCH2;
          case 3: // OUCH3
            return OUCH3;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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.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.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);
    }

    public importTable_result() {
    }

    public importTable_result(
      TableExistsException ouch1,
      AccumuloException ouch2,
      AccumuloSecurityException ouch3)
    {
      this();
      this.ouch1 = ouch1;
      this.ouch2 = ouch2;
      this.ouch3 = ouch3;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public importTable_result(importTable_result other) {
      if (other.isSetOuch1()) {
        this.ouch1 = new TableExistsException(other.ouch1);
      }
      if (other.isSetOuch2()) {
        this.ouch2 = new AccumuloException(other.ouch2);
      }
      if (other.isSetOuch3()) {
        this.ouch3 = new AccumuloSecurityException(other.ouch3);
      }
    }

    public importTable_result deepCopy() {
      return new importTable_result(this);
    }

    @Override
    public void clear() {
      this.ouch1 = null;
      this.ouch2 = null;
      this.ouch3 = null;
    }

    public TableExistsException getOuch1() {
      return this.ouch1;
    }

    public importTable_result setOuch1(TableExistsException ouch1) {
      this.ouch1 = ouch1;
      return this;
    }

    public void unsetOuch1() {
      this.ouch1 = null;
    }

    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch1() {
      return this.ouch1 != null;
    }

    public void setOuch1IsSet(boolean value) {
      if (!value) {
        this.ouch1 = null;
      }
    }

    public AccumuloException getOuch2() {
      return this.ouch2;
    }

    public importTable_result setOuch2(AccumuloException ouch2) {
      this.ouch2 = ouch2;
      return this;
    }

    public void unsetOuch2() {
      this.ouch2 = null;
    }

    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch2() {
      return this.ouch2 != null;
    }

    public void setOuch2IsSet(boolean value) {
      if (!value) {
        this.ouch2 = null;
      }
    }

    public AccumuloSecurityException getOuch3() {
      return this.ouch3;
    }

    public importTable_result setOuch3(AccumuloSecurityException ouch3) {
      this.ouch3 = ouch3;
      return this;
    }

    public void unsetOuch3() {
      this.ouch3 = null;
    }

    /** Returns true if field ouch3 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch3() {
      return this.ouch3 != null;
    }

    public void setOuch3IsSet(boolean value) {
      if (!value) {
        this.ouch3 = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case OUCH1:
        if (value == null) {
          unsetOuch1();
        } else {
          setOuch1((TableExistsException)value);
        }
        break;

      case OUCH2:
        if (value == null) {
          unsetOuch2();
        } else {
          setOuch2((AccumuloException)value);
        }
        break;

      case OUCH3:
        if (value == null) {
          unsetOuch3();
        } else {
          setOuch3((AccumuloSecurityException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case OUCH1:
        return getOuch1();

      case OUCH2:
        return getOuch2();

      case OUCH3:
        return getOuch3();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case OUCH1:
        return isSetOuch1();
      case OUCH2:
        return isSetOuch2();
      case OUCH3:
        return isSetOuch3();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof importTable_result)
        return this.equals((importTable_result)that);
      return false;
    }

    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();
      if (this_present_ouch1 || that_present_ouch1) {
        if (!(this_present_ouch1 && that_present_ouch1))
          return false;
        if (!this.ouch1.equals(that.ouch1))
          return false;
      }

      boolean this_present_ouch2 = true && this.isSetOuch2();
      boolean that_present_ouch2 = true && that.isSetOuch2();
      if (this_present_ouch2 || that_present_ouch2) {
        if (!(this_present_ouch2 && that_present_ouch2))
          return false;
        if (!this.ouch2.equals(that.ouch2))
          return false;
      }

      boolean this_present_ouch3 = true && this.isSetOuch3();
      boolean that_present_ouch3 = true && that.isSetOuch3();
      if (this_present_ouch3 || that_present_ouch3) {
        if (!(this_present_ouch3 && that_present_ouch3))
          return false;
        if (!this.ouch3.equals(that.ouch3))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
      if (isSetOuch1())
        hashCode = hashCode * 8191 + ouch1.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
      if (isSetOuch2())
        hashCode = hashCode * 8191 + ouch2.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
      if (isSetOuch3())
        hashCode = hashCode * 8191 + ouch3.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(importTable_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch1()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch2()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch3()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch3, other.ouch3);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("importTable_result(");
      boolean first = true;

      sb.append("ouch1:");
      if (this.ouch1 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch1);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch2:");
      if (this.ouch2 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch2);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch3:");
      if (this.ouch3 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch3);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class importTable_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public importTable_resultStandardScheme getScheme() {
        return new importTable_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // OUCH1
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch1 = new TableExistsException();
                struct.ouch1.read(iprot);
                struct.setOuch1IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OUCH2
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch2 = new AccumuloException();
                struct.ouch2.read(iprot);
                struct.setOuch2IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // OUCH3
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch3 = new AccumuloSecurityException();
                struct.ouch3.read(iprot);
                struct.setOuch3IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, importTable_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.ouch1 != null) {
          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
          struct.ouch1.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch2 != null) {
          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
          struct.ouch2.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch3 != null) {
          oprot.writeFieldBegin(OUCH3_FIELD_DESC);
          struct.ouch3.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class importTable_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public importTable_resultTupleScheme getScheme() {
        return new importTable_resultTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetOuch2()) {
          optionals.set(1);
        }
        if (struct.isSetOuch3()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetOuch1()) {
          struct.ouch1.write(oprot);
        }
        if (struct.isSetOuch2()) {
          struct.ouch2.write(oprot);
        }
        if (struct.isSetOuch3()) {
          struct.ouch3.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, importTable_result struct) throws org.apache.thrift.TException {
        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);
          struct.setOuch1IsSet(true);
        }
        if (incoming.get(1)) {
          struct.ouch2 = new AccumuloException();
          struct.ouch2.read(iprot);
          struct.setOuch2IsSet(true);
        }
        if (incoming.get(2)) {
          struct.ouch3 = new AccumuloSecurityException();
          struct.ouch3.read(iprot);
          struct.setOuch3IsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("listSplits_args");

    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField 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 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 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. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      LOGIN((short)1, "login"),
      TABLE_NAME((short)2, "tableName"),
      MAX_SPLITS((short)3, "maxSplits");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // LOGIN
            return LOGIN;
          case 2: // TABLE_NAME
            return TABLE_NAME;
          case 3: // MAX_SPLITS
            return MAX_SPLITS;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __MAXSPLITS_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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 = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(listSplits_args.class, metaDataMap);
    }

    public listSplits_args() {
    }

    public listSplits_args(
      java.nio.ByteBuffer login,
      java.lang.String tableName,
      int maxSplits)
    {
      this();
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      this.tableName = tableName;
      this.maxSplits = maxSplits;
      setMaxSplitsIsSet(true);
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public listSplits_args(listSplits_args other) {
      __isset_bitfield = other.__isset_bitfield;
      if (other.isSetLogin()) {
        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
      }
      if (other.isSetTableName()) {
        this.tableName = other.tableName;
      }
      this.maxSplits = other.maxSplits;
    }

    public listSplits_args deepCopy() {
      return new listSplits_args(this);
    }

    @Override
    public void clear() {
      this.login = null;
      this.tableName = null;
      setMaxSplitsIsSet(false);
      this.maxSplits = 0;
    }

    public byte[] getLogin() {
      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
      return login == null ? null : login.array();
    }

    public java.nio.ByteBuffer bufferForLogin() {
      return org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    public listSplits_args setLogin(byte[] login) {
      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
      return this;
    }

    public listSplits_args setLogin(java.nio.ByteBuffer login) {
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      return this;
    }

    public void unsetLogin() {
      this.login = null;
    }

    /** Returns true if field login is set (has been assigned a value) and false otherwise */
    public boolean isSetLogin() {
      return this.login != null;
    }

    public void setLoginIsSet(boolean value) {
      if (!value) {
        this.login = null;
      }
    }

    public java.lang.String getTableName() {
      return this.tableName;
    }

    public listSplits_args setTableName(java.lang.String tableName) {
      this.tableName = tableName;
      return this;
    }

    public void unsetTableName() {
      this.tableName = null;
    }

    /** Returns true if field tableName is set (has been assigned a value) and false otherwise */
    public boolean isSetTableName() {
      return this.tableName != null;
    }

    public void setTableNameIsSet(boolean value) {
      if (!value) {
        this.tableName = null;
      }
    }

    public int getMaxSplits() {
      return this.maxSplits;
    }

    public listSplits_args setMaxSplits(int maxSplits) {
      this.maxSplits = maxSplits;
      setMaxSplitsIsSet(true);
      return this;
    }

    public void unsetMaxSplits() {
      __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 org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __MAXSPLITS_ISSET_ID);
    }

    public void setMaxSplitsIsSet(boolean value) {
      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __MAXSPLITS_ISSET_ID, value);
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case LOGIN:
        if (value == null) {
          unsetLogin();
        } else {
          if (value instanceof byte[]) {
            setLogin((byte[])value);
          } else {
            setLogin((java.nio.ByteBuffer)value);
          }
        }
        break;

      case TABLE_NAME:
        if (value == null) {
          unsetTableName();
        } else {
          setTableName((java.lang.String)value);
        }
        break;

      case MAX_SPLITS:
        if (value == null) {
          unsetMaxSplits();
        } else {
          setMaxSplits((java.lang.Integer)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case LOGIN:
        return getLogin();

      case TABLE_NAME:
        return getTableName();

      case MAX_SPLITS:
        return getMaxSplits();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case LOGIN:
        return isSetLogin();
      case TABLE_NAME:
        return isSetTableName();
      case MAX_SPLITS:
        return isSetMaxSplits();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof listSplits_args)
        return this.equals((listSplits_args)that);
      return false;
    }

    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();
      if (this_present_login || that_present_login) {
        if (!(this_present_login && that_present_login))
          return false;
        if (!this.login.equals(that.login))
          return false;
      }

      boolean this_present_tableName = true && this.isSetTableName();
      boolean that_present_tableName = true && that.isSetTableName();
      if (this_present_tableName || that_present_tableName) {
        if (!(this_present_tableName && that_present_tableName))
          return false;
        if (!this.tableName.equals(that.tableName))
          return false;
      }

      boolean this_present_maxSplits = true;
      boolean that_present_maxSplits = true;
      if (this_present_maxSplits || that_present_maxSplits) {
        if (!(this_present_maxSplits && that_present_maxSplits))
          return false;
        if (this.maxSplits != that.maxSplits)
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
      if (isSetLogin())
        hashCode = hashCode * 8191 + login.hashCode();

      hashCode = hashCode * 8191 + ((isSetTableName()) ? 131071 : 524287);
      if (isSetTableName())
        hashCode = hashCode * 8191 + tableName.hashCode();

      hashCode = hashCode * 8191 + maxSplits;

      return hashCode;
    }

    @Override
    public int compareTo(listSplits_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLogin()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetTableName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.tableName, other.tableName);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetMaxSplits()).compareTo(other.isSetMaxSplits());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetMaxSplits()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.maxSplits, other.maxSplits);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("listSplits_args(");
      boolean first = true;

      sb.append("login:");
      if (this.login == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.login, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("tableName:");
      if (this.tableName == null) {
        sb.append("null");
      } else {
        sb.append(this.tableName);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("maxSplits:");
      sb.append(this.maxSplits);
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, 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;
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class listSplits_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public listSplits_argsStandardScheme getScheme() {
        return new listSplits_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // LOGIN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.login = iprot.readBinary();
                struct.setLoginIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // TABLE_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.tableName = iprot.readString();
                struct.setTableNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // MAX_SPLITS
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.maxSplits = iprot.readI32();
                struct.setMaxSplitsIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, listSplits_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.login != null) {
          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
          oprot.writeBinary(struct.login);
          oprot.writeFieldEnd();
        }
        if (struct.tableName != null) {
          oprot.writeFieldBegin(TABLE_NAME_FIELD_DESC);
          oprot.writeString(struct.tableName);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldBegin(MAX_SPLITS_FIELD_DESC);
        oprot.writeI32(struct.maxSplits);
        oprot.writeFieldEnd();
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    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 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 {
        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);
        }
        if (struct.isSetTableName()) {
          optionals.set(1);
        }
        if (struct.isSetMaxSplits()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetLogin()) {
          oprot.writeBinary(struct.login);
        }
        if (struct.isSetTableName()) {
          oprot.writeString(struct.tableName);
        }
        if (struct.isSetMaxSplits()) {
          oprot.writeI32(struct.maxSplits);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, listSplits_args struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.tableName = iprot.readString();
          struct.setTableNameIsSet(true);
        }
        if (incoming.get(2)) {
          struct.maxSplits = iprot.readI32();
          struct.setMaxSplitsIsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("listSplits_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.LIST, (short)0);
    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final 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.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new listSplits_resultStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new listSplits_resultTupleSchemeFactory();

    public java.util.List<java.nio.ByteBuffer> success; // required
    public AccumuloException ouch1; // required
    public AccumuloSecurityException ouch2; // required
    public TableNotFoundException ouch3; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      OUCH1((short)1, "ouch1"),
      OUCH2((short)2, "ouch2"),
      OUCH3((short)3, "ouch3");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // OUCH1
            return OUCH1;
          case 2: // OUCH2
            return OUCH2;
          case 3: // OUCH3
            return OUCH3;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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.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.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);
    }

    public listSplits_result() {
    }

    public listSplits_result(
      java.util.List<java.nio.ByteBuffer> success,
      AccumuloException ouch1,
      AccumuloSecurityException ouch2,
      TableNotFoundException ouch3)
    {
      this();
      this.success = success;
      this.ouch1 = ouch1;
      this.ouch2 = ouch2;
      this.ouch3 = ouch3;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public listSplits_result(listSplits_result other) {
      if (other.isSetSuccess()) {
        java.util.List<java.nio.ByteBuffer> __this__success = new java.util.ArrayList<java.nio.ByteBuffer>(other.success);
        this.success = __this__success;
      }
      if (other.isSetOuch1()) {
        this.ouch1 = new AccumuloException(other.ouch1);
      }
      if (other.isSetOuch2()) {
        this.ouch2 = new AccumuloSecurityException(other.ouch2);
      }
      if (other.isSetOuch3()) {
        this.ouch3 = new TableNotFoundException(other.ouch3);
      }
    }

    public listSplits_result deepCopy() {
      return new listSplits_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ouch1 = null;
      this.ouch2 = null;
      this.ouch3 = null;
    }

    public int getSuccessSize() {
      return (this.success == null) ? 0 : this.success.size();
    }

    public java.util.Iterator<java.nio.ByteBuffer> getSuccessIterator() {
      return (this.success == null) ? null : this.success.iterator();
    }

    public void addToSuccess(java.nio.ByteBuffer elem) {
      if (this.success == null) {
        this.success = new java.util.ArrayList<java.nio.ByteBuffer>();
      }
      this.success.add(elem);
    }

    public java.util.List<java.nio.ByteBuffer> getSuccess() {
      return this.success;
    }

    public listSplits_result setSuccess(java.util.List<java.nio.ByteBuffer> success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return this.success != null;
    }

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public AccumuloException getOuch1() {
      return this.ouch1;
    }

    public listSplits_result setOuch1(AccumuloException ouch1) {
      this.ouch1 = ouch1;
      return this;
    }

    public void unsetOuch1() {
      this.ouch1 = null;
    }

    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch1() {
      return this.ouch1 != null;
    }

    public void setOuch1IsSet(boolean value) {
      if (!value) {
        this.ouch1 = null;
      }
    }

    public AccumuloSecurityException getOuch2() {
      return this.ouch2;
    }

    public listSplits_result setOuch2(AccumuloSecurityException ouch2) {
      this.ouch2 = ouch2;
      return this;
    }

    public void unsetOuch2() {
      this.ouch2 = null;
    }

    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch2() {
      return this.ouch2 != null;
    }

    public void setOuch2IsSet(boolean value) {
      if (!value) {
        this.ouch2 = null;
      }
    }

    public TableNotFoundException getOuch3() {
      return this.ouch3;
    }

    public listSplits_result setOuch3(TableNotFoundException ouch3) {
      this.ouch3 = ouch3;
      return this;
    }

    public void unsetOuch3() {
      this.ouch3 = null;
    }

    /** Returns true if field ouch3 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch3() {
      return this.ouch3 != null;
    }

    public void setOuch3IsSet(boolean value) {
      if (!value) {
        this.ouch3 = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.util.List<java.nio.ByteBuffer>)value);
        }
        break;

      case OUCH1:
        if (value == null) {
          unsetOuch1();
        } else {
          setOuch1((AccumuloException)value);
        }
        break;

      case OUCH2:
        if (value == null) {
          unsetOuch2();
        } else {
          setOuch2((AccumuloSecurityException)value);
        }
        break;

      case OUCH3:
        if (value == null) {
          unsetOuch3();
        } else {
          setOuch3((TableNotFoundException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case OUCH1:
        return getOuch1();

      case OUCH2:
        return getOuch2();

      case OUCH3:
        return getOuch3();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case OUCH1:
        return isSetOuch1();
      case OUCH2:
        return isSetOuch2();
      case OUCH3:
        return isSetOuch3();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof listSplits_result)
        return this.equals((listSplits_result)that);
      return false;
    }

    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();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ouch1 = true && this.isSetOuch1();
      boolean that_present_ouch1 = true && that.isSetOuch1();
      if (this_present_ouch1 || that_present_ouch1) {
        if (!(this_present_ouch1 && that_present_ouch1))
          return false;
        if (!this.ouch1.equals(that.ouch1))
          return false;
      }

      boolean this_present_ouch2 = true && this.isSetOuch2();
      boolean that_present_ouch2 = true && that.isSetOuch2();
      if (this_present_ouch2 || that_present_ouch2) {
        if (!(this_present_ouch2 && that_present_ouch2))
          return false;
        if (!this.ouch2.equals(that.ouch2))
          return false;
      }

      boolean this_present_ouch3 = true && this.isSetOuch3();
      boolean that_present_ouch3 = true && that.isSetOuch3();
      if (this_present_ouch3 || that_present_ouch3) {
        if (!(this_present_ouch3 && that_present_ouch3))
          return false;
        if (!this.ouch3.equals(that.ouch3))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
      if (isSetSuccess())
        hashCode = hashCode * 8191 + success.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
      if (isSetOuch1())
        hashCode = hashCode * 8191 + ouch1.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
      if (isSetOuch2())
        hashCode = hashCode * 8191 + ouch2.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
      if (isSetOuch3())
        hashCode = hashCode * 8191 + ouch3.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(listSplits_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch1()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch2()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch3()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch3, other.ouch3);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("listSplits_result(");
      boolean first = true;

      sb.append("success:");
      if (this.success == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.success, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch1:");
      if (this.ouch1 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch1);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch2:");
      if (this.ouch2 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch2);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch3:");
      if (this.ouch3 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch3);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class listSplits_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public listSplits_resultStandardScheme getScheme() {
        return new listSplits_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
                {
                  org.apache.thrift.protocol.TList _list276 = iprot.readListBegin();
                  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();
                    struct.success.add(_elem277);
                  }
                  iprot.readListEnd();
                }
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // OUCH1
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch1 = new AccumuloException();
                struct.ouch1.read(iprot);
                struct.setOuch1IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OUCH2
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch2 = new AccumuloSecurityException();
                struct.ouch2.read(iprot);
                struct.setOuch2IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // OUCH3
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch3 = new TableNotFoundException();
                struct.ouch3.read(iprot);
                struct.setOuch3IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, listSplits_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRING, struct.success.size()));
            for (java.nio.ByteBuffer _iter279 : struct.success)
            {
              oprot.writeBinary(_iter279);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.ouch1 != null) {
          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
          struct.ouch1.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch2 != null) {
          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
          struct.ouch2.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch3 != null) {
          oprot.writeFieldBegin(OUCH3_FIELD_DESC);
          struct.ouch3.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    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 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 {
        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);
        }
        if (struct.isSetOuch1()) {
          optionals.set(1);
        }
        if (struct.isSetOuch2()) {
          optionals.set(2);
        }
        if (struct.isSetOuch3()) {
          optionals.set(3);
        }
        oprot.writeBitSet(optionals, 4);
        if (struct.isSetSuccess()) {
          {
            oprot.writeI32(struct.success.size());
            for (java.nio.ByteBuffer _iter280 : struct.success)
            {
              oprot.writeBinary(_iter280);
            }
          }
        }
        if (struct.isSetOuch1()) {
          struct.ouch1.write(oprot);
        }
        if (struct.isSetOuch2()) {
          struct.ouch2.write(oprot);
        }
        if (struct.isSetOuch3()) {
          struct.ouch3.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, listSplits_result struct) throws org.apache.thrift.TException {
        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 java.util.ArrayList<java.nio.ByteBuffer>(_list281.size);
            java.nio.ByteBuffer _elem282;
            for (int _i283 = 0; _i283 < _list281.size; ++_i283)
            {
              _elem282 = iprot.readBinary();
              struct.success.add(_elem282);
            }
          }
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ouch1 = new AccumuloException();
          struct.ouch1.read(iprot);
          struct.setOuch1IsSet(true);
        }
        if (incoming.get(2)) {
          struct.ouch2 = new AccumuloSecurityException();
          struct.ouch2.read(iprot);
          struct.setOuch2IsSet(true);
        }
        if (incoming.get(3)) {
          struct.ouch3 = new TableNotFoundException();
          struct.ouch3.read(iprot);
          struct.setOuch3IsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("listTables_args");

    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new listTables_argsStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new listTables_argsTupleSchemeFactory();

    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 java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // LOGIN
            return LOGIN;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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 = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(listTables_args.class, metaDataMap);
    }

    public listTables_args() {
    }

    public listTables_args(
      java.nio.ByteBuffer login)
    {
      this();
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public listTables_args(listTables_args other) {
      if (other.isSetLogin()) {
        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
      }
    }

    public listTables_args deepCopy() {
      return new listTables_args(this);
    }

    @Override
    public void clear() {
      this.login = null;
    }

    public byte[] getLogin() {
      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
      return login == null ? null : login.array();
    }

    public java.nio.ByteBuffer bufferForLogin() {
      return org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    public listTables_args setLogin(byte[] login) {
      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
      return this;
    }

    public listTables_args setLogin(java.nio.ByteBuffer login) {
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      return this;
    }

    public void unsetLogin() {
      this.login = null;
    }

    /** Returns true if field login is set (has been assigned a value) and false otherwise */
    public boolean isSetLogin() {
      return this.login != null;
    }

    public void setLoginIsSet(boolean value) {
      if (!value) {
        this.login = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case LOGIN:
        if (value == null) {
          unsetLogin();
        } else {
          if (value instanceof byte[]) {
            setLogin((byte[])value);
          } else {
            setLogin((java.nio.ByteBuffer)value);
          }
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case LOGIN:
        return getLogin();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case LOGIN:
        return isSetLogin();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof listTables_args)
        return this.equals((listTables_args)that);
      return false;
    }

    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();
      if (this_present_login || that_present_login) {
        if (!(this_present_login && that_present_login))
          return false;
        if (!this.login.equals(that.login))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
      if (isSetLogin())
        hashCode = hashCode * 8191 + login.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(listTables_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLogin()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("listTables_args(");
      boolean first = true;

      sb.append("login:");
      if (this.login == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.login, sb);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class listTables_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public listTables_argsStandardScheme getScheme() {
        return new listTables_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // LOGIN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.login = iprot.readBinary();
                struct.setLoginIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, listTables_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.login != null) {
          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
          oprot.writeBinary(struct.login);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class listTables_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public listTables_argsTupleScheme getScheme() {
        return new listTables_argsTupleScheme();
      }
    }

    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 {
        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);
        }
        oprot.writeBitSet(optionals, 1);
        if (struct.isSetLogin()) {
          oprot.writeBinary(struct.login);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, listTables_args struct) throws org.apache.thrift.TException {
        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);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("listTables_result");

    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 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 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 java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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 = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(listTables_result.class, metaDataMap);
    }

    public listTables_result() {
    }

    public listTables_result(
      java.util.Set<java.lang.String> success)
    {
      this();
      this.success = success;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public listTables_result(listTables_result other) {
      if (other.isSetSuccess()) {
        java.util.Set<java.lang.String> __this__success = new java.util.HashSet<java.lang.String>(other.success);
        this.success = __this__success;
      }
    }

    public listTables_result deepCopy() {
      return new listTables_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
    }

    public int getSuccessSize() {
      return (this.success == null) ? 0 : this.success.size();
    }

    public java.util.Iterator<java.lang.String> getSuccessIterator() {
      return (this.success == null) ? null : this.success.iterator();
    }

    public void addToSuccess(java.lang.String elem) {
      if (this.success == null) {
        this.success = new java.util.HashSet<java.lang.String>();
      }
      this.success.add(elem);
    }

    public java.util.Set<java.lang.String> getSuccess() {
      return this.success;
    }

    public listTables_result setSuccess(java.util.Set<java.lang.String> success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return this.success != null;
    }

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.util.Set<java.lang.String>)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof listTables_result)
        return this.equals((listTables_result)that);
      return false;
    }

    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();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
      if (isSetSuccess())
        hashCode = hashCode * 8191 + success.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(listTables_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("listTables_result(");
      boolean first = true;

      sb.append("success:");
      if (this.success == null) {
        sb.append("null");
      } else {
        sb.append(this.success);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class listTables_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public listTables_resultStandardScheme getScheme() {
        return new listTables_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.SET) {
                {
                  org.apache.thrift.protocol.TSet _set284 = iprot.readSetBegin();
                  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();
                    struct.success.add(_elem285);
                  }
                  iprot.readSetEnd();
                }
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, listTables_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          {
            oprot.writeSetBegin(new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRING, struct.success.size()));
            for (java.lang.String _iter287 : struct.success)
            {
              oprot.writeString(_iter287);
            }
            oprot.writeSetEnd();
          }
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    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 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 {
        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);
        }
        oprot.writeBitSet(optionals, 1);
        if (struct.isSetSuccess()) {
          {
            oprot.writeI32(struct.success.size());
            for (java.lang.String _iter288 : struct.success)
            {
              oprot.writeString(_iter288);
            }
          }
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, listTables_result struct) throws org.apache.thrift.TException {
        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 java.util.HashSet<java.lang.String>(2*_set289.size);
            java.lang.String _elem290;
            for (int _i291 = 0; _i291 < _set289.size; ++_i291)
            {
              _elem290 = iprot.readString();
              struct.success.add(_elem290);
            }
          }
          struct.setSuccessIsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("listIterators_args");

    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField 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.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new listIterators_argsStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new listIterators_argsTupleSchemeFactory();

    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 java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // LOGIN
            return LOGIN;
          case 2: // TABLE_NAME
            return TABLE_NAME;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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 = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(listIterators_args.class, metaDataMap);
    }

    public listIterators_args() {
    }

    public listIterators_args(
      java.nio.ByteBuffer login,
      java.lang.String tableName)
    {
      this();
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      this.tableName = tableName;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public listIterators_args(listIterators_args other) {
      if (other.isSetLogin()) {
        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
      }
      if (other.isSetTableName()) {
        this.tableName = other.tableName;
      }
    }

    public listIterators_args deepCopy() {
      return new listIterators_args(this);
    }

    @Override
    public void clear() {
      this.login = null;
      this.tableName = null;
    }

    public byte[] getLogin() {
      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
      return login == null ? null : login.array();
    }

    public java.nio.ByteBuffer bufferForLogin() {
      return org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    public listIterators_args setLogin(byte[] login) {
      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
      return this;
    }

    public listIterators_args setLogin(java.nio.ByteBuffer login) {
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      return this;
    }

    public void unsetLogin() {
      this.login = null;
    }

    /** Returns true if field login is set (has been assigned a value) and false otherwise */
    public boolean isSetLogin() {
      return this.login != null;
    }

    public void setLoginIsSet(boolean value) {
      if (!value) {
        this.login = null;
      }
    }

    public java.lang.String getTableName() {
      return this.tableName;
    }

    public listIterators_args setTableName(java.lang.String tableName) {
      this.tableName = tableName;
      return this;
    }

    public void unsetTableName() {
      this.tableName = null;
    }

    /** Returns true if field tableName is set (has been assigned a value) and false otherwise */
    public boolean isSetTableName() {
      return this.tableName != null;
    }

    public void setTableNameIsSet(boolean value) {
      if (!value) {
        this.tableName = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case LOGIN:
        if (value == null) {
          unsetLogin();
        } else {
          if (value instanceof byte[]) {
            setLogin((byte[])value);
          } else {
            setLogin((java.nio.ByteBuffer)value);
          }
        }
        break;

      case TABLE_NAME:
        if (value == null) {
          unsetTableName();
        } else {
          setTableName((java.lang.String)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case LOGIN:
        return getLogin();

      case TABLE_NAME:
        return getTableName();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case LOGIN:
        return isSetLogin();
      case TABLE_NAME:
        return isSetTableName();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof listIterators_args)
        return this.equals((listIterators_args)that);
      return false;
    }

    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();
      if (this_present_login || that_present_login) {
        if (!(this_present_login && that_present_login))
          return false;
        if (!this.login.equals(that.login))
          return false;
      }

      boolean this_present_tableName = true && this.isSetTableName();
      boolean that_present_tableName = true && that.isSetTableName();
      if (this_present_tableName || that_present_tableName) {
        if (!(this_present_tableName && that_present_tableName))
          return false;
        if (!this.tableName.equals(that.tableName))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
      if (isSetLogin())
        hashCode = hashCode * 8191 + login.hashCode();

      hashCode = hashCode * 8191 + ((isSetTableName()) ? 131071 : 524287);
      if (isSetTableName())
        hashCode = hashCode * 8191 + tableName.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(listIterators_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLogin()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetTableName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.tableName, other.tableName);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("listIterators_args(");
      boolean first = true;

      sb.append("login:");
      if (this.login == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.login, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("tableName:");
      if (this.tableName == null) {
        sb.append("null");
      } else {
        sb.append(this.tableName);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class listIterators_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public listIterators_argsStandardScheme getScheme() {
        return new listIterators_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // LOGIN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.login = iprot.readBinary();
                struct.setLoginIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // TABLE_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.tableName = iprot.readString();
                struct.setTableNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, listIterators_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.login != null) {
          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
          oprot.writeBinary(struct.login);
          oprot.writeFieldEnd();
        }
        if (struct.tableName != null) {
          oprot.writeFieldBegin(TABLE_NAME_FIELD_DESC);
          oprot.writeString(struct.tableName);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    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 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 {
        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);
        }
        if (struct.isSetTableName()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetLogin()) {
          oprot.writeBinary(struct.login);
        }
        if (struct.isSetTableName()) {
          oprot.writeString(struct.tableName);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, listIterators_args struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.tableName = iprot.readString();
          struct.setTableNameIsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("listIterators_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.MAP, (short)0);
    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField OUCH3_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch3", org.apache.thrift.protocol.TType.STRUCT, (short)3);

    private static final 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 java.util.Map<java.lang.String,java.util.Set<IteratorScope>> success; // required
    public AccumuloException ouch1; // required
    public AccumuloSecurityException ouch2; // required
    public TableNotFoundException ouch3; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      OUCH1((short)1, "ouch1"),
      OUCH2((short)2, "ouch2"),
      OUCH3((short)3, "ouch3");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // OUCH1
            return OUCH1;
          case 2: // OUCH2
            return OUCH2;
          case 3: // OUCH3
            return OUCH3;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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.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.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);
    }

    public listIterators_result() {
    }

    public listIterators_result(
      java.util.Map<java.lang.String,java.util.Set<IteratorScope>> success,
      AccumuloException ouch1,
      AccumuloSecurityException ouch2,
      TableNotFoundException ouch3)
    {
      this();
      this.success = success;
      this.ouch1 = ouch1;
      this.ouch2 = ouch2;
      this.ouch3 = ouch3;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public listIterators_result(listIterators_result other) {
      if (other.isSetSuccess()) {
        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()) {

          java.lang.String other_element_key = other_element.getKey();
          java.util.Set<IteratorScope> other_element_value = other_element.getValue();

          java.lang.String __this__success_copy_key = other_element_key;

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

          __this__success.put(__this__success_copy_key, __this__success_copy_value);
        }
        this.success = __this__success;
      }
      if (other.isSetOuch1()) {
        this.ouch1 = new AccumuloException(other.ouch1);
      }
      if (other.isSetOuch2()) {
        this.ouch2 = new AccumuloSecurityException(other.ouch2);
      }
      if (other.isSetOuch3()) {
        this.ouch3 = new TableNotFoundException(other.ouch3);
      }
    }

    public listIterators_result deepCopy() {
      return new listIterators_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ouch1 = null;
      this.ouch2 = null;
      this.ouch3 = null;
    }

    public int getSuccessSize() {
      return (this.success == null) ? 0 : this.success.size();
    }

    public void putToSuccess(java.lang.String key, java.util.Set<IteratorScope> val) {
      if (this.success == null) {
        this.success = new java.util.HashMap<java.lang.String,java.util.Set<IteratorScope>>();
      }
      this.success.put(key, val);
    }

    public java.util.Map<java.lang.String,java.util.Set<IteratorScope>> getSuccess() {
      return this.success;
    }

    public listIterators_result setSuccess(java.util.Map<java.lang.String,java.util.Set<IteratorScope>> success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return this.success != null;
    }

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public AccumuloException getOuch1() {
      return this.ouch1;
    }

    public listIterators_result setOuch1(AccumuloException ouch1) {
      this.ouch1 = ouch1;
      return this;
    }

    public void unsetOuch1() {
      this.ouch1 = null;
    }

    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch1() {
      return this.ouch1 != null;
    }

    public void setOuch1IsSet(boolean value) {
      if (!value) {
        this.ouch1 = null;
      }
    }

    public AccumuloSecurityException getOuch2() {
      return this.ouch2;
    }

    public listIterators_result setOuch2(AccumuloSecurityException ouch2) {
      this.ouch2 = ouch2;
      return this;
    }

    public void unsetOuch2() {
      this.ouch2 = null;
    }

    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch2() {
      return this.ouch2 != null;
    }

    public void setOuch2IsSet(boolean value) {
      if (!value) {
        this.ouch2 = null;
      }
    }

    public TableNotFoundException getOuch3() {
      return this.ouch3;
    }

    public listIterators_result setOuch3(TableNotFoundException ouch3) {
      this.ouch3 = ouch3;
      return this;
    }

    public void unsetOuch3() {
      this.ouch3 = null;
    }

    /** Returns true if field ouch3 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch3() {
      return this.ouch3 != null;
    }

    public void setOuch3IsSet(boolean value) {
      if (!value) {
        this.ouch3 = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.util.Map<java.lang.String,java.util.Set<IteratorScope>>)value);
        }
        break;

      case OUCH1:
        if (value == null) {
          unsetOuch1();
        } else {
          setOuch1((AccumuloException)value);
        }
        break;

      case OUCH2:
        if (value == null) {
          unsetOuch2();
        } else {
          setOuch2((AccumuloSecurityException)value);
        }
        break;

      case OUCH3:
        if (value == null) {
          unsetOuch3();
        } else {
          setOuch3((TableNotFoundException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case OUCH1:
        return getOuch1();

      case OUCH2:
        return getOuch2();

      case OUCH3:
        return getOuch3();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case OUCH1:
        return isSetOuch1();
      case OUCH2:
        return isSetOuch2();
      case OUCH3:
        return isSetOuch3();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof listIterators_result)
        return this.equals((listIterators_result)that);
      return false;
    }

    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();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ouch1 = true && this.isSetOuch1();
      boolean that_present_ouch1 = true && that.isSetOuch1();
      if (this_present_ouch1 || that_present_ouch1) {
        if (!(this_present_ouch1 && that_present_ouch1))
          return false;
        if (!this.ouch1.equals(that.ouch1))
          return false;
      }

      boolean this_present_ouch2 = true && this.isSetOuch2();
      boolean that_present_ouch2 = true && that.isSetOuch2();
      if (this_present_ouch2 || that_present_ouch2) {
        if (!(this_present_ouch2 && that_present_ouch2))
          return false;
        if (!this.ouch2.equals(that.ouch2))
          return false;
      }

      boolean this_present_ouch3 = true && this.isSetOuch3();
      boolean that_present_ouch3 = true && that.isSetOuch3();
      if (this_present_ouch3 || that_present_ouch3) {
        if (!(this_present_ouch3 && that_present_ouch3))
          return false;
        if (!this.ouch3.equals(that.ouch3))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
      if (isSetSuccess())
        hashCode = hashCode * 8191 + success.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
      if (isSetOuch1())
        hashCode = hashCode * 8191 + ouch1.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
      if (isSetOuch2())
        hashCode = hashCode * 8191 + ouch2.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
      if (isSetOuch3())
        hashCode = hashCode * 8191 + ouch3.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(listIterators_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch1()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch2()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch3()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch3, other.ouch3);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("listIterators_result(");
      boolean first = true;

      sb.append("success:");
      if (this.success == null) {
        sb.append("null");
      } else {
        sb.append(this.success);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch1:");
      if (this.ouch1 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch1);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch2:");
      if (this.ouch2 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch2);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch3:");
      if (this.ouch3 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch3);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class listIterators_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public listIterators_resultStandardScheme getScheme() {
        return new listIterators_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.MAP) {
                {
                  org.apache.thrift.protocol.TMap _map292 = iprot.readMapBegin();
                  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 java.util.HashSet<IteratorScope>(2*_set296.size);
                      IteratorScope _elem297;
                      for (int _i298 = 0; _i298 < _set296.size; ++_i298)
                      {
                        _elem297 = org.apache.accumulo.proxy.thrift.IteratorScope.findByValue(iprot.readI32());
                        _val294.add(_elem297);
                      }
                      iprot.readSetEnd();
                    }
                    struct.success.put(_key293, _val294);
                  }
                  iprot.readMapEnd();
                }
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // OUCH1
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch1 = new AccumuloException();
                struct.ouch1.read(iprot);
                struct.setOuch1IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OUCH2
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch2 = new AccumuloSecurityException();
                struct.ouch2.read(iprot);
                struct.setOuch2IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // OUCH3
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch3 = new TableNotFoundException();
                struct.ouch3.read(iprot);
                struct.setOuch3IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, listIterators_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          {
            oprot.writeMapBegin(new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.SET, struct.success.size()));
            for (java.util.Map.Entry<java.lang.String, java.util.Set<IteratorScope>> _iter299 : struct.success.entrySet())
            {
              oprot.writeString(_iter299.getKey());
              {
                oprot.writeSetBegin(new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.I32, _iter299.getValue().size()));
                for (IteratorScope _iter300 : _iter299.getValue())
                {
                  oprot.writeI32(_iter300.getValue());
                }
                oprot.writeSetEnd();
              }
            }
            oprot.writeMapEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.ouch1 != null) {
          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
          struct.ouch1.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch2 != null) {
          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
          struct.ouch2.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch3 != null) {
          oprot.writeFieldBegin(OUCH3_FIELD_DESC);
          struct.ouch3.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class listIterators_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public listIterators_resultTupleScheme getScheme() {
        return new listIterators_resultTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetOuch1()) {
          optionals.set(1);
        }
        if (struct.isSetOuch2()) {
          optionals.set(2);
        }
        if (struct.isSetOuch3()) {
          optionals.set(3);
        }
        oprot.writeBitSet(optionals, 4);
        if (struct.isSetSuccess()) {
          {
            oprot.writeI32(struct.success.size());
            for (java.util.Map.Entry<java.lang.String, java.util.Set<IteratorScope>> _iter301 : struct.success.entrySet())
            {
              oprot.writeString(_iter301.getKey());
              {
                oprot.writeI32(_iter301.getValue().size());
                for (IteratorScope _iter302 : _iter301.getValue())
                {
                  oprot.writeI32(_iter302.getValue());
                }
              }
            }
          }
        }
        if (struct.isSetOuch1()) {
          struct.ouch1.write(oprot);
        }
        if (struct.isSetOuch2()) {
          struct.ouch2.write(oprot);
        }
        if (struct.isSetOuch3()) {
          struct.ouch3.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, listIterators_result struct) throws org.apache.thrift.TException {
        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 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 java.util.HashSet<IteratorScope>(2*_set307.size);
                IteratorScope _elem308;
                for (int _i309 = 0; _i309 < _set307.size; ++_i309)
                {
                  _elem308 = org.apache.accumulo.proxy.thrift.IteratorScope.findByValue(iprot.readI32());
                  _val305.add(_elem308);
                }
              }
              struct.success.put(_key304, _val305);
            }
          }
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ouch1 = new AccumuloException();
          struct.ouch1.read(iprot);
          struct.setOuch1IsSet(true);
        }
        if (incoming.get(2)) {
          struct.ouch2 = new AccumuloSecurityException();
          struct.ouch2.read(iprot);
          struct.setOuch2IsSet(true);
        }
        if (incoming.get(3)) {
          struct.ouch3 = new TableNotFoundException();
          struct.ouch3.read(iprot);
          struct.setOuch3IsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("listConstraints_args");

    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField 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.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new listConstraints_argsStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new listConstraints_argsTupleSchemeFactory();

    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 java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // LOGIN
            return LOGIN;
          case 2: // TABLE_NAME
            return TABLE_NAME;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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 = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(listConstraints_args.class, metaDataMap);
    }

    public listConstraints_args() {
    }

    public listConstraints_args(
      java.nio.ByteBuffer login,
      java.lang.String tableName)
    {
      this();
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      this.tableName = tableName;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public listConstraints_args(listConstraints_args other) {
      if (other.isSetLogin()) {
        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
      }
      if (other.isSetTableName()) {
        this.tableName = other.tableName;
      }
    }

    public listConstraints_args deepCopy() {
      return new listConstraints_args(this);
    }

    @Override
    public void clear() {
      this.login = null;
      this.tableName = null;
    }

    public byte[] getLogin() {
      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
      return login == null ? null : login.array();
    }

    public java.nio.ByteBuffer bufferForLogin() {
      return org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    public listConstraints_args setLogin(byte[] login) {
      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
      return this;
    }

    public listConstraints_args setLogin(java.nio.ByteBuffer login) {
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      return this;
    }

    public void unsetLogin() {
      this.login = null;
    }

    /** Returns true if field login is set (has been assigned a value) and false otherwise */
    public boolean isSetLogin() {
      return this.login != null;
    }

    public void setLoginIsSet(boolean value) {
      if (!value) {
        this.login = null;
      }
    }

    public java.lang.String getTableName() {
      return this.tableName;
    }

    public listConstraints_args setTableName(java.lang.String tableName) {
      this.tableName = tableName;
      return this;
    }

    public void unsetTableName() {
      this.tableName = null;
    }

    /** Returns true if field tableName is set (has been assigned a value) and false otherwise */
    public boolean isSetTableName() {
      return this.tableName != null;
    }

    public void setTableNameIsSet(boolean value) {
      if (!value) {
        this.tableName = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case LOGIN:
        if (value == null) {
          unsetLogin();
        } else {
          if (value instanceof byte[]) {
            setLogin((byte[])value);
          } else {
            setLogin((java.nio.ByteBuffer)value);
          }
        }
        break;

      case TABLE_NAME:
        if (value == null) {
          unsetTableName();
        } else {
          setTableName((java.lang.String)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case LOGIN:
        return getLogin();

      case TABLE_NAME:
        return getTableName();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case LOGIN:
        return isSetLogin();
      case TABLE_NAME:
        return isSetTableName();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof listConstraints_args)
        return this.equals((listConstraints_args)that);
      return false;
    }

    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();
      if (this_present_login || that_present_login) {
        if (!(this_present_login && that_present_login))
          return false;
        if (!this.login.equals(that.login))
          return false;
      }

      boolean this_present_tableName = true && this.isSetTableName();
      boolean that_present_tableName = true && that.isSetTableName();
      if (this_present_tableName || that_present_tableName) {
        if (!(this_present_tableName && that_present_tableName))
          return false;
        if (!this.tableName.equals(that.tableName))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
      if (isSetLogin())
        hashCode = hashCode * 8191 + login.hashCode();

      hashCode = hashCode * 8191 + ((isSetTableName()) ? 131071 : 524287);
      if (isSetTableName())
        hashCode = hashCode * 8191 + tableName.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(listConstraints_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLogin()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetTableName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.tableName, other.tableName);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("listConstraints_args(");
      boolean first = true;

      sb.append("login:");
      if (this.login == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.login, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("tableName:");
      if (this.tableName == null) {
        sb.append("null");
      } else {
        sb.append(this.tableName);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class listConstraints_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public listConstraints_argsStandardScheme getScheme() {
        return new listConstraints_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // LOGIN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.login = iprot.readBinary();
                struct.setLoginIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // TABLE_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.tableName = iprot.readString();
                struct.setTableNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, listConstraints_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.login != null) {
          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
          oprot.writeBinary(struct.login);
          oprot.writeFieldEnd();
        }
        if (struct.tableName != null) {
          oprot.writeFieldBegin(TABLE_NAME_FIELD_DESC);
          oprot.writeString(struct.tableName);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    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 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 {
        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);
        }
        if (struct.isSetTableName()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetLogin()) {
          oprot.writeBinary(struct.login);
        }
        if (struct.isSetTableName()) {
          oprot.writeString(struct.tableName);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, listConstraints_args struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.tableName = iprot.readString();
          struct.setTableNameIsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("listConstraints_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.MAP, (short)0);
    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField OUCH3_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch3", org.apache.thrift.protocol.TType.STRUCT, (short)3);

    private static final 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 java.util.Map<java.lang.String,java.lang.Integer> success; // required
    public AccumuloException ouch1; // required
    public AccumuloSecurityException ouch2; // required
    public TableNotFoundException ouch3; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      OUCH1((short)1, "ouch1"),
      OUCH2((short)2, "ouch2"),
      OUCH3((short)3, "ouch3");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // OUCH1
            return OUCH1;
          case 2: // OUCH2
            return OUCH2;
          case 3: // OUCH3
            return OUCH3;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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.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.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);
    }

    public listConstraints_result() {
    }

    public listConstraints_result(
      java.util.Map<java.lang.String,java.lang.Integer> success,
      AccumuloException ouch1,
      AccumuloSecurityException ouch2,
      TableNotFoundException ouch3)
    {
      this();
      this.success = success;
      this.ouch1 = ouch1;
      this.ouch2 = ouch2;
      this.ouch3 = ouch3;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public listConstraints_result(listConstraints_result other) {
      if (other.isSetSuccess()) {
        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()) {
        this.ouch1 = new AccumuloException(other.ouch1);
      }
      if (other.isSetOuch2()) {
        this.ouch2 = new AccumuloSecurityException(other.ouch2);
      }
      if (other.isSetOuch3()) {
        this.ouch3 = new TableNotFoundException(other.ouch3);
      }
    }

    public listConstraints_result deepCopy() {
      return new listConstraints_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ouch1 = null;
      this.ouch2 = null;
      this.ouch3 = null;
    }

    public int getSuccessSize() {
      return (this.success == null) ? 0 : this.success.size();
    }

    public void putToSuccess(java.lang.String key, int val) {
      if (this.success == null) {
        this.success = new java.util.HashMap<java.lang.String,java.lang.Integer>();
      }
      this.success.put(key, val);
    }

    public java.util.Map<java.lang.String,java.lang.Integer> getSuccess() {
      return this.success;
    }

    public listConstraints_result setSuccess(java.util.Map<java.lang.String,java.lang.Integer> success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return this.success != null;
    }

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public AccumuloException getOuch1() {
      return this.ouch1;
    }

    public listConstraints_result setOuch1(AccumuloException ouch1) {
      this.ouch1 = ouch1;
      return this;
    }

    public void unsetOuch1() {
      this.ouch1 = null;
    }

    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch1() {
      return this.ouch1 != null;
    }

    public void setOuch1IsSet(boolean value) {
      if (!value) {
        this.ouch1 = null;
      }
    }

    public AccumuloSecurityException getOuch2() {
      return this.ouch2;
    }

    public listConstraints_result setOuch2(AccumuloSecurityException ouch2) {
      this.ouch2 = ouch2;
      return this;
    }

    public void unsetOuch2() {
      this.ouch2 = null;
    }

    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch2() {
      return this.ouch2 != null;
    }

    public void setOuch2IsSet(boolean value) {
      if (!value) {
        this.ouch2 = null;
      }
    }

    public TableNotFoundException getOuch3() {
      return this.ouch3;
    }

    public listConstraints_result setOuch3(TableNotFoundException ouch3) {
      this.ouch3 = ouch3;
      return this;
    }

    public void unsetOuch3() {
      this.ouch3 = null;
    }

    /** Returns true if field ouch3 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch3() {
      return this.ouch3 != null;
    }

    public void setOuch3IsSet(boolean value) {
      if (!value) {
        this.ouch3 = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.util.Map<java.lang.String,java.lang.Integer>)value);
        }
        break;

      case OUCH1:
        if (value == null) {
          unsetOuch1();
        } else {
          setOuch1((AccumuloException)value);
        }
        break;

      case OUCH2:
        if (value == null) {
          unsetOuch2();
        } else {
          setOuch2((AccumuloSecurityException)value);
        }
        break;

      case OUCH3:
        if (value == null) {
          unsetOuch3();
        } else {
          setOuch3((TableNotFoundException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case OUCH1:
        return getOuch1();

      case OUCH2:
        return getOuch2();

      case OUCH3:
        return getOuch3();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case OUCH1:
        return isSetOuch1();
      case OUCH2:
        return isSetOuch2();
      case OUCH3:
        return isSetOuch3();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof listConstraints_result)
        return this.equals((listConstraints_result)that);
      return false;
    }

    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();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ouch1 = true && this.isSetOuch1();
      boolean that_present_ouch1 = true && that.isSetOuch1();
      if (this_present_ouch1 || that_present_ouch1) {
        if (!(this_present_ouch1 && that_present_ouch1))
          return false;
        if (!this.ouch1.equals(that.ouch1))
          return false;
      }

      boolean this_present_ouch2 = true && this.isSetOuch2();
      boolean that_present_ouch2 = true && that.isSetOuch2();
      if (this_present_ouch2 || that_present_ouch2) {
        if (!(this_present_ouch2 && that_present_ouch2))
          return false;
        if (!this.ouch2.equals(that.ouch2))
          return false;
      }

      boolean this_present_ouch3 = true && this.isSetOuch3();
      boolean that_present_ouch3 = true && that.isSetOuch3();
      if (this_present_ouch3 || that_present_ouch3) {
        if (!(this_present_ouch3 && that_present_ouch3))
          return false;
        if (!this.ouch3.equals(that.ouch3))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
      if (isSetSuccess())
        hashCode = hashCode * 8191 + success.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
      if (isSetOuch1())
        hashCode = hashCode * 8191 + ouch1.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
      if (isSetOuch2())
        hashCode = hashCode * 8191 + ouch2.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
      if (isSetOuch3())
        hashCode = hashCode * 8191 + ouch3.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(listConstraints_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch1()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch2()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch3()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch3, other.ouch3);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("listConstraints_result(");
      boolean first = true;

      sb.append("success:");
      if (this.success == null) {
        sb.append("null");
      } else {
        sb.append(this.success);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch1:");
      if (this.ouch1 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch1);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch2:");
      if (this.ouch2 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch2);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch3:");
      if (this.ouch3 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch3);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class listConstraints_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public listConstraints_resultStandardScheme getScheme() {
        return new listConstraints_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.MAP) {
                {
                  org.apache.thrift.protocol.TMap _map310 = iprot.readMapBegin();
                  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)
                  {
                    _key311 = iprot.readString();
                    _val312 = iprot.readI32();
                    struct.success.put(_key311, _val312);
                  }
                  iprot.readMapEnd();
                }
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // OUCH1
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch1 = new AccumuloException();
                struct.ouch1.read(iprot);
                struct.setOuch1IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OUCH2
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch2 = new AccumuloSecurityException();
                struct.ouch2.read(iprot);
                struct.setOuch2IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // OUCH3
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch3 = new TableNotFoundException();
                struct.ouch3.read(iprot);
                struct.setOuch3IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, listConstraints_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          {
            oprot.writeMapBegin(new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.I32, struct.success.size()));
            for (java.util.Map.Entry<java.lang.String, java.lang.Integer> _iter314 : struct.success.entrySet())
            {
              oprot.writeString(_iter314.getKey());
              oprot.writeI32(_iter314.getValue());
            }
            oprot.writeMapEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.ouch1 != null) {
          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
          struct.ouch1.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch2 != null) {
          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
          struct.ouch2.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch3 != null) {
          oprot.writeFieldBegin(OUCH3_FIELD_DESC);
          struct.ouch3.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class listConstraints_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public listConstraints_resultTupleScheme getScheme() {
        return new listConstraints_resultTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetOuch1()) {
          optionals.set(1);
        }
        if (struct.isSetOuch2()) {
          optionals.set(2);
        }
        if (struct.isSetOuch3()) {
          optionals.set(3);
        }
        oprot.writeBitSet(optionals, 4);
        if (struct.isSetSuccess()) {
          {
            oprot.writeI32(struct.success.size());
            for (java.util.Map.Entry<java.lang.String, java.lang.Integer> _iter315 : struct.success.entrySet())
            {
              oprot.writeString(_iter315.getKey());
              oprot.writeI32(_iter315.getValue());
            }
          }
        }
        if (struct.isSetOuch1()) {
          struct.ouch1.write(oprot);
        }
        if (struct.isSetOuch2()) {
          struct.ouch2.write(oprot);
        }
        if (struct.isSetOuch3()) {
          struct.ouch3.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, listConstraints_result struct) throws org.apache.thrift.TException {
        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 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)
            {
              _key317 = iprot.readString();
              _val318 = iprot.readI32();
              struct.success.put(_key317, _val318);
            }
          }
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ouch1 = new AccumuloException();
          struct.ouch1.read(iprot);
          struct.setOuch1IsSet(true);
        }
        if (incoming.get(2)) {
          struct.ouch2 = new AccumuloSecurityException();
          struct.ouch2.read(iprot);
          struct.setOuch2IsSet(true);
        }
        if (incoming.get(3)) {
          struct.ouch3 = new TableNotFoundException();
          struct.ouch3.read(iprot);
          struct.setOuch3IsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("mergeTablets_args");

    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField 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 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 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 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 {
      LOGIN((short)1, "login"),
      TABLE_NAME((short)2, "tableName"),
      START_ROW((short)3, "startRow"),
      END_ROW((short)4, "endRow");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // LOGIN
            return LOGIN;
          case 2: // TABLE_NAME
            return TABLE_NAME;
          case 3: // START_ROW
            return START_ROW;
          case 4: // END_ROW
            return END_ROW;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.START_ROW, new org.apache.thrift.meta_data.FieldMetaData("startRow", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          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 = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(mergeTablets_args.class, metaDataMap);
    }

    public mergeTablets_args() {
    }

    public mergeTablets_args(
      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);
      this.tableName = tableName;
      this.startRow = org.apache.thrift.TBaseHelper.copyBinary(startRow);
      this.endRow = org.apache.thrift.TBaseHelper.copyBinary(endRow);
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public mergeTablets_args(mergeTablets_args other) {
      if (other.isSetLogin()) {
        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
      }
      if (other.isSetTableName()) {
        this.tableName = other.tableName;
      }
      if (other.isSetStartRow()) {
        this.startRow = org.apache.thrift.TBaseHelper.copyBinary(other.startRow);
      }
      if (other.isSetEndRow()) {
        this.endRow = org.apache.thrift.TBaseHelper.copyBinary(other.endRow);
      }
    }

    public mergeTablets_args deepCopy() {
      return new mergeTablets_args(this);
    }

    @Override
    public void clear() {
      this.login = null;
      this.tableName = null;
      this.startRow = null;
      this.endRow = null;
    }

    public byte[] getLogin() {
      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
      return login == null ? null : login.array();
    }

    public java.nio.ByteBuffer bufferForLogin() {
      return org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    public mergeTablets_args setLogin(byte[] login) {
      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
      return this;
    }

    public mergeTablets_args setLogin(java.nio.ByteBuffer login) {
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      return this;
    }

    public void unsetLogin() {
      this.login = null;
    }

    /** Returns true if field login is set (has been assigned a value) and false otherwise */
    public boolean isSetLogin() {
      return this.login != null;
    }

    public void setLoginIsSet(boolean value) {
      if (!value) {
        this.login = null;
      }
    }

    public java.lang.String getTableName() {
      return this.tableName;
    }

    public mergeTablets_args setTableName(java.lang.String tableName) {
      this.tableName = tableName;
      return this;
    }

    public void unsetTableName() {
      this.tableName = null;
    }

    /** Returns true if field tableName is set (has been assigned a value) and false otherwise */
    public boolean isSetTableName() {
      return this.tableName != null;
    }

    public void setTableNameIsSet(boolean value) {
      if (!value) {
        this.tableName = null;
      }
    }

    public byte[] getStartRow() {
      setStartRow(org.apache.thrift.TBaseHelper.rightSize(startRow));
      return startRow == null ? null : startRow.array();
    }

    public java.nio.ByteBuffer bufferForStartRow() {
      return org.apache.thrift.TBaseHelper.copyBinary(startRow);
    }

    public mergeTablets_args setStartRow(byte[] startRow) {
      this.startRow = startRow == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(startRow.clone());
      return this;
    }

    public mergeTablets_args setStartRow(java.nio.ByteBuffer startRow) {
      this.startRow = org.apache.thrift.TBaseHelper.copyBinary(startRow);
      return this;
    }

    public void unsetStartRow() {
      this.startRow = null;
    }

    /** Returns true if field startRow is set (has been assigned a value) and false otherwise */
    public boolean isSetStartRow() {
      return this.startRow != null;
    }

    public void setStartRowIsSet(boolean value) {
      if (!value) {
        this.startRow = null;
      }
    }

    public byte[] getEndRow() {
      setEndRow(org.apache.thrift.TBaseHelper.rightSize(endRow));
      return endRow == null ? null : endRow.array();
    }

    public java.nio.ByteBuffer bufferForEndRow() {
      return org.apache.thrift.TBaseHelper.copyBinary(endRow);
    }

    public mergeTablets_args setEndRow(byte[] endRow) {
      this.endRow = endRow == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(endRow.clone());
      return this;
    }

    public mergeTablets_args setEndRow(java.nio.ByteBuffer endRow) {
      this.endRow = org.apache.thrift.TBaseHelper.copyBinary(endRow);
      return this;
    }

    public void unsetEndRow() {
      this.endRow = null;
    }

    /** Returns true if field endRow is set (has been assigned a value) and false otherwise */
    public boolean isSetEndRow() {
      return this.endRow != null;
    }

    public void setEndRowIsSet(boolean value) {
      if (!value) {
        this.endRow = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case LOGIN:
        if (value == null) {
          unsetLogin();
        } else {
          if (value instanceof byte[]) {
            setLogin((byte[])value);
          } else {
            setLogin((java.nio.ByteBuffer)value);
          }
        }
        break;

      case TABLE_NAME:
        if (value == null) {
          unsetTableName();
        } else {
          setTableName((java.lang.String)value);
        }
        break;

      case START_ROW:
        if (value == null) {
          unsetStartRow();
        } else {
          if (value instanceof byte[]) {
            setStartRow((byte[])value);
          } else {
            setStartRow((java.nio.ByteBuffer)value);
          }
        }
        break;

      case END_ROW:
        if (value == null) {
          unsetEndRow();
        } else {
          if (value instanceof byte[]) {
            setEndRow((byte[])value);
          } else {
            setEndRow((java.nio.ByteBuffer)value);
          }
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case LOGIN:
        return getLogin();

      case TABLE_NAME:
        return getTableName();

      case START_ROW:
        return getStartRow();

      case END_ROW:
        return getEndRow();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case LOGIN:
        return isSetLogin();
      case TABLE_NAME:
        return isSetTableName();
      case START_ROW:
        return isSetStartRow();
      case END_ROW:
        return isSetEndRow();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof mergeTablets_args)
        return this.equals((mergeTablets_args)that);
      return false;
    }

    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();
      if (this_present_login || that_present_login) {
        if (!(this_present_login && that_present_login))
          return false;
        if (!this.login.equals(that.login))
          return false;
      }

      boolean this_present_tableName = true && this.isSetTableName();
      boolean that_present_tableName = true && that.isSetTableName();
      if (this_present_tableName || that_present_tableName) {
        if (!(this_present_tableName && that_present_tableName))
          return false;
        if (!this.tableName.equals(that.tableName))
          return false;
      }

      boolean this_present_startRow = true && this.isSetStartRow();
      boolean that_present_startRow = true && that.isSetStartRow();
      if (this_present_startRow || that_present_startRow) {
        if (!(this_present_startRow && that_present_startRow))
          return false;
        if (!this.startRow.equals(that.startRow))
          return false;
      }

      boolean this_present_endRow = true && this.isSetEndRow();
      boolean that_present_endRow = true && that.isSetEndRow();
      if (this_present_endRow || that_present_endRow) {
        if (!(this_present_endRow && that_present_endRow))
          return false;
        if (!this.endRow.equals(that.endRow))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
      if (isSetLogin())
        hashCode = hashCode * 8191 + login.hashCode();

      hashCode = hashCode * 8191 + ((isSetTableName()) ? 131071 : 524287);
      if (isSetTableName())
        hashCode = hashCode * 8191 + tableName.hashCode();

      hashCode = hashCode * 8191 + ((isSetStartRow()) ? 131071 : 524287);
      if (isSetStartRow())
        hashCode = hashCode * 8191 + startRow.hashCode();

      hashCode = hashCode * 8191 + ((isSetEndRow()) ? 131071 : 524287);
      if (isSetEndRow())
        hashCode = hashCode * 8191 + endRow.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(mergeTablets_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLogin()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetTableName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.tableName, other.tableName);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetStartRow()).compareTo(other.isSetStartRow());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetStartRow()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.startRow, other.startRow);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetEndRow()).compareTo(other.isSetEndRow());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetEndRow()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.endRow, other.endRow);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("mergeTablets_args(");
      boolean first = true;

      sb.append("login:");
      if (this.login == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.login, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("tableName:");
      if (this.tableName == null) {
        sb.append("null");
      } else {
        sb.append(this.tableName);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("startRow:");
      if (this.startRow == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.startRow, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("endRow:");
      if (this.endRow == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.endRow, sb);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class mergeTablets_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public mergeTablets_argsStandardScheme getScheme() {
        return new mergeTablets_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // LOGIN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.login = iprot.readBinary();
                struct.setLoginIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // TABLE_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.tableName = iprot.readString();
                struct.setTableNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // START_ROW
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.startRow = iprot.readBinary();
                struct.setStartRowIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // END_ROW
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.endRow = iprot.readBinary();
                struct.setEndRowIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, mergeTablets_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.login != null) {
          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
          oprot.writeBinary(struct.login);
          oprot.writeFieldEnd();
        }
        if (struct.tableName != null) {
          oprot.writeFieldBegin(TABLE_NAME_FIELD_DESC);
          oprot.writeString(struct.tableName);
          oprot.writeFieldEnd();
        }
        if (struct.startRow != null) {
          oprot.writeFieldBegin(START_ROW_FIELD_DESC);
          oprot.writeBinary(struct.startRow);
          oprot.writeFieldEnd();
        }
        if (struct.endRow != null) {
          oprot.writeFieldBegin(END_ROW_FIELD_DESC);
          oprot.writeBinary(struct.endRow);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    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 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 {
        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);
        }
        if (struct.isSetTableName()) {
          optionals.set(1);
        }
        if (struct.isSetStartRow()) {
          optionals.set(2);
        }
        if (struct.isSetEndRow()) {
          optionals.set(3);
        }
        oprot.writeBitSet(optionals, 4);
        if (struct.isSetLogin()) {
          oprot.writeBinary(struct.login);
        }
        if (struct.isSetTableName()) {
          oprot.writeString(struct.tableName);
        }
        if (struct.isSetStartRow()) {
          oprot.writeBinary(struct.startRow);
        }
        if (struct.isSetEndRow()) {
          oprot.writeBinary(struct.endRow);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, mergeTablets_args struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.tableName = iprot.readString();
          struct.setTableNameIsSet(true);
        }
        if (incoming.get(2)) {
          struct.startRow = iprot.readBinary();
          struct.setStartRowIsSet(true);
        }
        if (incoming.get(3)) {
          struct.endRow = iprot.readBinary();
          struct.setEndRowIsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("mergeTablets_result");

    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField OUCH3_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch3", org.apache.thrift.protocol.TType.STRUCT, (short)3);

    private static final org.apache.thrift.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
    public TableNotFoundException ouch3; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      OUCH1((short)1, "ouch1"),
      OUCH2((short)2, "ouch2"),
      OUCH3((short)3, "ouch3");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // OUCH1
            return OUCH1;
          case 2: // OUCH2
            return OUCH2;
          case 3: // OUCH3
            return OUCH3;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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.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.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);
    }

    public mergeTablets_result() {
    }

    public mergeTablets_result(
      AccumuloException ouch1,
      AccumuloSecurityException ouch2,
      TableNotFoundException ouch3)
    {
      this();
      this.ouch1 = ouch1;
      this.ouch2 = ouch2;
      this.ouch3 = ouch3;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public mergeTablets_result(mergeTablets_result other) {
      if (other.isSetOuch1()) {
        this.ouch1 = new AccumuloException(other.ouch1);
      }
      if (other.isSetOuch2()) {
        this.ouch2 = new AccumuloSecurityException(other.ouch2);
      }
      if (other.isSetOuch3()) {
        this.ouch3 = new TableNotFoundException(other.ouch3);
      }
    }

    public mergeTablets_result deepCopy() {
      return new mergeTablets_result(this);
    }

    @Override
    public void clear() {
      this.ouch1 = null;
      this.ouch2 = null;
      this.ouch3 = null;
    }

    public AccumuloException getOuch1() {
      return this.ouch1;
    }

    public mergeTablets_result setOuch1(AccumuloException ouch1) {
      this.ouch1 = ouch1;
      return this;
    }

    public void unsetOuch1() {
      this.ouch1 = null;
    }

    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch1() {
      return this.ouch1 != null;
    }

    public void setOuch1IsSet(boolean value) {
      if (!value) {
        this.ouch1 = null;
      }
    }

    public AccumuloSecurityException getOuch2() {
      return this.ouch2;
    }

    public mergeTablets_result setOuch2(AccumuloSecurityException ouch2) {
      this.ouch2 = ouch2;
      return this;
    }

    public void unsetOuch2() {
      this.ouch2 = null;
    }

    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch2() {
      return this.ouch2 != null;
    }

    public void setOuch2IsSet(boolean value) {
      if (!value) {
        this.ouch2 = null;
      }
    }

    public TableNotFoundException getOuch3() {
      return this.ouch3;
    }

    public mergeTablets_result setOuch3(TableNotFoundException ouch3) {
      this.ouch3 = ouch3;
      return this;
    }

    public void unsetOuch3() {
      this.ouch3 = null;
    }

    /** Returns true if field ouch3 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch3() {
      return this.ouch3 != null;
    }

    public void setOuch3IsSet(boolean value) {
      if (!value) {
        this.ouch3 = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case OUCH1:
        if (value == null) {
          unsetOuch1();
        } else {
          setOuch1((AccumuloException)value);
        }
        break;

      case OUCH2:
        if (value == null) {
          unsetOuch2();
        } else {
          setOuch2((AccumuloSecurityException)value);
        }
        break;

      case OUCH3:
        if (value == null) {
          unsetOuch3();
        } else {
          setOuch3((TableNotFoundException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case OUCH1:
        return getOuch1();

      case OUCH2:
        return getOuch2();

      case OUCH3:
        return getOuch3();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case OUCH1:
        return isSetOuch1();
      case OUCH2:
        return isSetOuch2();
      case OUCH3:
        return isSetOuch3();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof mergeTablets_result)
        return this.equals((mergeTablets_result)that);
      return false;
    }

    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();
      if (this_present_ouch1 || that_present_ouch1) {
        if (!(this_present_ouch1 && that_present_ouch1))
          return false;
        if (!this.ouch1.equals(that.ouch1))
          return false;
      }

      boolean this_present_ouch2 = true && this.isSetOuch2();
      boolean that_present_ouch2 = true && that.isSetOuch2();
      if (this_present_ouch2 || that_present_ouch2) {
        if (!(this_present_ouch2 && that_present_ouch2))
          return false;
        if (!this.ouch2.equals(that.ouch2))
          return false;
      }

      boolean this_present_ouch3 = true && this.isSetOuch3();
      boolean that_present_ouch3 = true && that.isSetOuch3();
      if (this_present_ouch3 || that_present_ouch3) {
        if (!(this_present_ouch3 && that_present_ouch3))
          return false;
        if (!this.ouch3.equals(that.ouch3))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
      if (isSetOuch1())
        hashCode = hashCode * 8191 + ouch1.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
      if (isSetOuch2())
        hashCode = hashCode * 8191 + ouch2.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
      if (isSetOuch3())
        hashCode = hashCode * 8191 + ouch3.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(mergeTablets_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch1()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch2()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch3()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch3, other.ouch3);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("mergeTablets_result(");
      boolean first = true;

      sb.append("ouch1:");
      if (this.ouch1 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch1);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch2:");
      if (this.ouch2 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch2);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch3:");
      if (this.ouch3 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch3);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class mergeTablets_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public mergeTablets_resultStandardScheme getScheme() {
        return new mergeTablets_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // OUCH1
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch1 = new AccumuloException();
                struct.ouch1.read(iprot);
                struct.setOuch1IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OUCH2
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch2 = new AccumuloSecurityException();
                struct.ouch2.read(iprot);
                struct.setOuch2IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // OUCH3
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch3 = new TableNotFoundException();
                struct.ouch3.read(iprot);
                struct.setOuch3IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, mergeTablets_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.ouch1 != null) {
          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
          struct.ouch1.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch2 != null) {
          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
          struct.ouch2.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch3 != null) {
          oprot.writeFieldBegin(OUCH3_FIELD_DESC);
          struct.ouch3.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class mergeTablets_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public mergeTablets_resultTupleScheme getScheme() {
        return new mergeTablets_resultTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetOuch2()) {
          optionals.set(1);
        }
        if (struct.isSetOuch3()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetOuch1()) {
          struct.ouch1.write(oprot);
        }
        if (struct.isSetOuch2()) {
          struct.ouch2.write(oprot);
        }
        if (struct.isSetOuch3()) {
          struct.ouch3.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, mergeTablets_result struct) throws org.apache.thrift.TException {
        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);
          struct.setOuch1IsSet(true);
        }
        if (incoming.get(1)) {
          struct.ouch2 = new AccumuloSecurityException();
          struct.ouch2.read(iprot);
          struct.setOuch2IsSet(true);
        }
        if (incoming.get(2)) {
          struct.ouch3 = new TableNotFoundException();
          struct.ouch3.read(iprot);
          struct.setOuch3IsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("offlineTable_args");

    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField 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 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 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. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      LOGIN((short)1, "login"),
      TABLE_NAME((short)2, "tableName"),
      WAIT((short)3, "wait");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // LOGIN
            return LOGIN;
          case 2: // TABLE_NAME
            return TABLE_NAME;
          case 3: // WAIT
            return WAIT;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __WAIT_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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 = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(offlineTable_args.class, metaDataMap);
    }

    public offlineTable_args() {
      this.wait = false;

    }

    public offlineTable_args(
      java.nio.ByteBuffer login,
      java.lang.String tableName,
      boolean wait)
    {
      this();
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      this.tableName = tableName;
      this.wait = wait;
      setWaitIsSet(true);
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public offlineTable_args(offlineTable_args other) {
      __isset_bitfield = other.__isset_bitfield;
      if (other.isSetLogin()) {
        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
      }
      if (other.isSetTableName()) {
        this.tableName = other.tableName;
      }
      this.wait = other.wait;
    }

    public offlineTable_args deepCopy() {
      return new offlineTable_args(this);
    }

    @Override
    public void clear() {
      this.login = null;
      this.tableName = null;
      this.wait = false;

    }

    public byte[] getLogin() {
      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
      return login == null ? null : login.array();
    }

    public java.nio.ByteBuffer bufferForLogin() {
      return org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    public offlineTable_args setLogin(byte[] login) {
      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
      return this;
    }

    public offlineTable_args setLogin(java.nio.ByteBuffer login) {
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      return this;
    }

    public void unsetLogin() {
      this.login = null;
    }

    /** Returns true if field login is set (has been assigned a value) and false otherwise */
    public boolean isSetLogin() {
      return this.login != null;
    }

    public void setLoginIsSet(boolean value) {
      if (!value) {
        this.login = null;
      }
    }

    public java.lang.String getTableName() {
      return this.tableName;
    }

    public offlineTable_args setTableName(java.lang.String tableName) {
      this.tableName = tableName;
      return this;
    }

    public void unsetTableName() {
      this.tableName = null;
    }

    /** Returns true if field tableName is set (has been assigned a value) and false otherwise */
    public boolean isSetTableName() {
      return this.tableName != null;
    }

    public void setTableNameIsSet(boolean value) {
      if (!value) {
        this.tableName = null;
      }
    }

    public boolean isWait() {
      return this.wait;
    }

    public offlineTable_args setWait(boolean wait) {
      this.wait = wait;
      setWaitIsSet(true);
      return this;
    }

    public void unsetWait() {
      __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 org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __WAIT_ISSET_ID);
    }

    public void setWaitIsSet(boolean value) {
      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __WAIT_ISSET_ID, value);
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case LOGIN:
        if (value == null) {
          unsetLogin();
        } else {
          if (value instanceof byte[]) {
            setLogin((byte[])value);
          } else {
            setLogin((java.nio.ByteBuffer)value);
          }
        }
        break;

      case TABLE_NAME:
        if (value == null) {
          unsetTableName();
        } else {
          setTableName((java.lang.String)value);
        }
        break;

      case WAIT:
        if (value == null) {
          unsetWait();
        } else {
          setWait((java.lang.Boolean)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case LOGIN:
        return getLogin();

      case TABLE_NAME:
        return getTableName();

      case WAIT:
        return isWait();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case LOGIN:
        return isSetLogin();
      case TABLE_NAME:
        return isSetTableName();
      case WAIT:
        return isSetWait();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof offlineTable_args)
        return this.equals((offlineTable_args)that);
      return false;
    }

    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();
      if (this_present_login || that_present_login) {
        if (!(this_present_login && that_present_login))
          return false;
        if (!this.login.equals(that.login))
          return false;
      }

      boolean this_present_tableName = true && this.isSetTableName();
      boolean that_present_tableName = true && that.isSetTableName();
      if (this_present_tableName || that_present_tableName) {
        if (!(this_present_tableName && that_present_tableName))
          return false;
        if (!this.tableName.equals(that.tableName))
          return false;
      }

      boolean this_present_wait = true;
      boolean that_present_wait = true;
      if (this_present_wait || that_present_wait) {
        if (!(this_present_wait && that_present_wait))
          return false;
        if (this.wait != that.wait)
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
      if (isSetLogin())
        hashCode = hashCode * 8191 + login.hashCode();

      hashCode = hashCode * 8191 + ((isSetTableName()) ? 131071 : 524287);
      if (isSetTableName())
        hashCode = hashCode * 8191 + tableName.hashCode();

      hashCode = hashCode * 8191 + ((wait) ? 131071 : 524287);

      return hashCode;
    }

    @Override
    public int compareTo(offlineTable_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLogin()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetTableName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.tableName, other.tableName);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetWait()).compareTo(other.isSetWait());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetWait()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.wait, other.wait);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("offlineTable_args(");
      boolean first = true;

      sb.append("login:");
      if (this.login == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.login, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("tableName:");
      if (this.tableName == null) {
        sb.append("null");
      } else {
        sb.append(this.tableName);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("wait:");
      sb.append(this.wait);
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, 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;
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class offlineTable_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public offlineTable_argsStandardScheme getScheme() {
        return new offlineTable_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // LOGIN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.login = iprot.readBinary();
                struct.setLoginIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // TABLE_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.tableName = iprot.readString();
                struct.setTableNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // WAIT
              if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
                struct.wait = iprot.readBool();
                struct.setWaitIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, offlineTable_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.login != null) {
          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
          oprot.writeBinary(struct.login);
          oprot.writeFieldEnd();
        }
        if (struct.tableName != null) {
          oprot.writeFieldBegin(TABLE_NAME_FIELD_DESC);
          oprot.writeString(struct.tableName);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldBegin(WAIT_FIELD_DESC);
        oprot.writeBool(struct.wait);
        oprot.writeFieldEnd();
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    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 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 {
        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);
        }
        if (struct.isSetTableName()) {
          optionals.set(1);
        }
        if (struct.isSetWait()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetLogin()) {
          oprot.writeBinary(struct.login);
        }
        if (struct.isSetTableName()) {
          oprot.writeString(struct.tableName);
        }
        if (struct.isSetWait()) {
          oprot.writeBool(struct.wait);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, offlineTable_args struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.tableName = iprot.readString();
          struct.setTableNameIsSet(true);
        }
        if (incoming.get(2)) {
          struct.wait = iprot.readBool();
          struct.setWaitIsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("offlineTable_result");

    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField OUCH3_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch3", org.apache.thrift.protocol.TType.STRUCT, (short)3);

    private static final org.apache.thrift.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
    public TableNotFoundException ouch3; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      OUCH1((short)1, "ouch1"),
      OUCH2((short)2, "ouch2"),
      OUCH3((short)3, "ouch3");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // OUCH1
            return OUCH1;
          case 2: // OUCH2
            return OUCH2;
          case 3: // OUCH3
            return OUCH3;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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.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.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);
    }

    public offlineTable_result() {
    }

    public offlineTable_result(
      AccumuloException ouch1,
      AccumuloSecurityException ouch2,
      TableNotFoundException ouch3)
    {
      this();
      this.ouch1 = ouch1;
      this.ouch2 = ouch2;
      this.ouch3 = ouch3;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public offlineTable_result(offlineTable_result other) {
      if (other.isSetOuch1()) {
        this.ouch1 = new AccumuloException(other.ouch1);
      }
      if (other.isSetOuch2()) {
        this.ouch2 = new AccumuloSecurityException(other.ouch2);
      }
      if (other.isSetOuch3()) {
        this.ouch3 = new TableNotFoundException(other.ouch3);
      }
    }

    public offlineTable_result deepCopy() {
      return new offlineTable_result(this);
    }

    @Override
    public void clear() {
      this.ouch1 = null;
      this.ouch2 = null;
      this.ouch3 = null;
    }

    public AccumuloException getOuch1() {
      return this.ouch1;
    }

    public offlineTable_result setOuch1(AccumuloException ouch1) {
      this.ouch1 = ouch1;
      return this;
    }

    public void unsetOuch1() {
      this.ouch1 = null;
    }

    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch1() {
      return this.ouch1 != null;
    }

    public void setOuch1IsSet(boolean value) {
      if (!value) {
        this.ouch1 = null;
      }
    }

    public AccumuloSecurityException getOuch2() {
      return this.ouch2;
    }

    public offlineTable_result setOuch2(AccumuloSecurityException ouch2) {
      this.ouch2 = ouch2;
      return this;
    }

    public void unsetOuch2() {
      this.ouch2 = null;
    }

    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch2() {
      return this.ouch2 != null;
    }

    public void setOuch2IsSet(boolean value) {
      if (!value) {
        this.ouch2 = null;
      }
    }

    public TableNotFoundException getOuch3() {
      return this.ouch3;
    }

    public offlineTable_result setOuch3(TableNotFoundException ouch3) {
      this.ouch3 = ouch3;
      return this;
    }

    public void unsetOuch3() {
      this.ouch3 = null;
    }

    /** Returns true if field ouch3 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch3() {
      return this.ouch3 != null;
    }

    public void setOuch3IsSet(boolean value) {
      if (!value) {
        this.ouch3 = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case OUCH1:
        if (value == null) {
          unsetOuch1();
        } else {
          setOuch1((AccumuloException)value);
        }
        break;

      case OUCH2:
        if (value == null) {
          unsetOuch2();
        } else {
          setOuch2((AccumuloSecurityException)value);
        }
        break;

      case OUCH3:
        if (value == null) {
          unsetOuch3();
        } else {
          setOuch3((TableNotFoundException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case OUCH1:
        return getOuch1();

      case OUCH2:
        return getOuch2();

      case OUCH3:
        return getOuch3();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case OUCH1:
        return isSetOuch1();
      case OUCH2:
        return isSetOuch2();
      case OUCH3:
        return isSetOuch3();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof offlineTable_result)
        return this.equals((offlineTable_result)that);
      return false;
    }

    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();
      if (this_present_ouch1 || that_present_ouch1) {
        if (!(this_present_ouch1 && that_present_ouch1))
          return false;
        if (!this.ouch1.equals(that.ouch1))
          return false;
      }

      boolean this_present_ouch2 = true && this.isSetOuch2();
      boolean that_present_ouch2 = true && that.isSetOuch2();
      if (this_present_ouch2 || that_present_ouch2) {
        if (!(this_present_ouch2 && that_present_ouch2))
          return false;
        if (!this.ouch2.equals(that.ouch2))
          return false;
      }

      boolean this_present_ouch3 = true && this.isSetOuch3();
      boolean that_present_ouch3 = true && that.isSetOuch3();
      if (this_present_ouch3 || that_present_ouch3) {
        if (!(this_present_ouch3 && that_present_ouch3))
          return false;
        if (!this.ouch3.equals(that.ouch3))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
      if (isSetOuch1())
        hashCode = hashCode * 8191 + ouch1.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
      if (isSetOuch2())
        hashCode = hashCode * 8191 + ouch2.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
      if (isSetOuch3())
        hashCode = hashCode * 8191 + ouch3.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(offlineTable_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch1()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch2()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch3()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch3, other.ouch3);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("offlineTable_result(");
      boolean first = true;

      sb.append("ouch1:");
      if (this.ouch1 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch1);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch2:");
      if (this.ouch2 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch2);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch3:");
      if (this.ouch3 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch3);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class offlineTable_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public offlineTable_resultStandardScheme getScheme() {
        return new offlineTable_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // OUCH1
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch1 = new AccumuloException();
                struct.ouch1.read(iprot);
                struct.setOuch1IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OUCH2
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch2 = new AccumuloSecurityException();
                struct.ouch2.read(iprot);
                struct.setOuch2IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // OUCH3
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch3 = new TableNotFoundException();
                struct.ouch3.read(iprot);
                struct.setOuch3IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, offlineTable_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.ouch1 != null) {
          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
          struct.ouch1.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch2 != null) {
          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
          struct.ouch2.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch3 != null) {
          oprot.writeFieldBegin(OUCH3_FIELD_DESC);
          struct.ouch3.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class offlineTable_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public offlineTable_resultTupleScheme getScheme() {
        return new offlineTable_resultTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetOuch2()) {
          optionals.set(1);
        }
        if (struct.isSetOuch3()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetOuch1()) {
          struct.ouch1.write(oprot);
        }
        if (struct.isSetOuch2()) {
          struct.ouch2.write(oprot);
        }
        if (struct.isSetOuch3()) {
          struct.ouch3.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, offlineTable_result struct) throws org.apache.thrift.TException {
        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);
          struct.setOuch1IsSet(true);
        }
        if (incoming.get(1)) {
          struct.ouch2 = new AccumuloSecurityException();
          struct.ouch2.read(iprot);
          struct.setOuch2IsSet(true);
        }
        if (incoming.get(2)) {
          struct.ouch3 = new TableNotFoundException();
          struct.ouch3.read(iprot);
          struct.setOuch3IsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("onlineTable_args");

    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField 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 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 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. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      LOGIN((short)1, "login"),
      TABLE_NAME((short)2, "tableName"),
      WAIT((short)3, "wait");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // LOGIN
            return LOGIN;
          case 2: // TABLE_NAME
            return TABLE_NAME;
          case 3: // WAIT
            return WAIT;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __WAIT_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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 = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(onlineTable_args.class, metaDataMap);
    }

    public onlineTable_args() {
      this.wait = false;

    }

    public onlineTable_args(
      java.nio.ByteBuffer login,
      java.lang.String tableName,
      boolean wait)
    {
      this();
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      this.tableName = tableName;
      this.wait = wait;
      setWaitIsSet(true);
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public onlineTable_args(onlineTable_args other) {
      __isset_bitfield = other.__isset_bitfield;
      if (other.isSetLogin()) {
        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
      }
      if (other.isSetTableName()) {
        this.tableName = other.tableName;
      }
      this.wait = other.wait;
    }

    public onlineTable_args deepCopy() {
      return new onlineTable_args(this);
    }

    @Override
    public void clear() {
      this.login = null;
      this.tableName = null;
      this.wait = false;

    }

    public byte[] getLogin() {
      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
      return login == null ? null : login.array();
    }

    public java.nio.ByteBuffer bufferForLogin() {
      return org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    public onlineTable_args setLogin(byte[] login) {
      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
      return this;
    }

    public onlineTable_args setLogin(java.nio.ByteBuffer login) {
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      return this;
    }

    public void unsetLogin() {
      this.login = null;
    }

    /** Returns true if field login is set (has been assigned a value) and false otherwise */
    public boolean isSetLogin() {
      return this.login != null;
    }

    public void setLoginIsSet(boolean value) {
      if (!value) {
        this.login = null;
      }
    }

    public java.lang.String getTableName() {
      return this.tableName;
    }

    public onlineTable_args setTableName(java.lang.String tableName) {
      this.tableName = tableName;
      return this;
    }

    public void unsetTableName() {
      this.tableName = null;
    }

    /** Returns true if field tableName is set (has been assigned a value) and false otherwise */
    public boolean isSetTableName() {
      return this.tableName != null;
    }

    public void setTableNameIsSet(boolean value) {
      if (!value) {
        this.tableName = null;
      }
    }

    public boolean isWait() {
      return this.wait;
    }

    public onlineTable_args setWait(boolean wait) {
      this.wait = wait;
      setWaitIsSet(true);
      return this;
    }

    public void unsetWait() {
      __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 org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __WAIT_ISSET_ID);
    }

    public void setWaitIsSet(boolean value) {
      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __WAIT_ISSET_ID, value);
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case LOGIN:
        if (value == null) {
          unsetLogin();
        } else {
          if (value instanceof byte[]) {
            setLogin((byte[])value);
          } else {
            setLogin((java.nio.ByteBuffer)value);
          }
        }
        break;

      case TABLE_NAME:
        if (value == null) {
          unsetTableName();
        } else {
          setTableName((java.lang.String)value);
        }
        break;

      case WAIT:
        if (value == null) {
          unsetWait();
        } else {
          setWait((java.lang.Boolean)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case LOGIN:
        return getLogin();

      case TABLE_NAME:
        return getTableName();

      case WAIT:
        return isWait();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case LOGIN:
        return isSetLogin();
      case TABLE_NAME:
        return isSetTableName();
      case WAIT:
        return isSetWait();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof onlineTable_args)
        return this.equals((onlineTable_args)that);
      return false;
    }

    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();
      if (this_present_login || that_present_login) {
        if (!(this_present_login && that_present_login))
          return false;
        if (!this.login.equals(that.login))
          return false;
      }

      boolean this_present_tableName = true && this.isSetTableName();
      boolean that_present_tableName = true && that.isSetTableName();
      if (this_present_tableName || that_present_tableName) {
        if (!(this_present_tableName && that_present_tableName))
          return false;
        if (!this.tableName.equals(that.tableName))
          return false;
      }

      boolean this_present_wait = true;
      boolean that_present_wait = true;
      if (this_present_wait || that_present_wait) {
        if (!(this_present_wait && that_present_wait))
          return false;
        if (this.wait != that.wait)
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
      if (isSetLogin())
        hashCode = hashCode * 8191 + login.hashCode();

      hashCode = hashCode * 8191 + ((isSetTableName()) ? 131071 : 524287);
      if (isSetTableName())
        hashCode = hashCode * 8191 + tableName.hashCode();

      hashCode = hashCode * 8191 + ((wait) ? 131071 : 524287);

      return hashCode;
    }

    @Override
    public int compareTo(onlineTable_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLogin()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetTableName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.tableName, other.tableName);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetWait()).compareTo(other.isSetWait());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetWait()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.wait, other.wait);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("onlineTable_args(");
      boolean first = true;

      sb.append("login:");
      if (this.login == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.login, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("tableName:");
      if (this.tableName == null) {
        sb.append("null");
      } else {
        sb.append(this.tableName);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("wait:");
      sb.append(this.wait);
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, 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;
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class onlineTable_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public onlineTable_argsStandardScheme getScheme() {
        return new onlineTable_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // LOGIN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.login = iprot.readBinary();
                struct.setLoginIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // TABLE_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.tableName = iprot.readString();
                struct.setTableNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // WAIT
              if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
                struct.wait = iprot.readBool();
                struct.setWaitIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, onlineTable_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.login != null) {
          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
          oprot.writeBinary(struct.login);
          oprot.writeFieldEnd();
        }
        if (struct.tableName != null) {
          oprot.writeFieldBegin(TABLE_NAME_FIELD_DESC);
          oprot.writeString(struct.tableName);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldBegin(WAIT_FIELD_DESC);
        oprot.writeBool(struct.wait);
        oprot.writeFieldEnd();
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    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 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 {
        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);
        }
        if (struct.isSetTableName()) {
          optionals.set(1);
        }
        if (struct.isSetWait()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetLogin()) {
          oprot.writeBinary(struct.login);
        }
        if (struct.isSetTableName()) {
          oprot.writeString(struct.tableName);
        }
        if (struct.isSetWait()) {
          oprot.writeBool(struct.wait);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, onlineTable_args struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.tableName = iprot.readString();
          struct.setTableNameIsSet(true);
        }
        if (incoming.get(2)) {
          struct.wait = iprot.readBool();
          struct.setWaitIsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("onlineTable_result");

    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField OUCH3_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch3", org.apache.thrift.protocol.TType.STRUCT, (short)3);

    private static final org.apache.thrift.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
    public TableNotFoundException ouch3; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      OUCH1((short)1, "ouch1"),
      OUCH2((short)2, "ouch2"),
      OUCH3((short)3, "ouch3");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // OUCH1
            return OUCH1;
          case 2: // OUCH2
            return OUCH2;
          case 3: // OUCH3
            return OUCH3;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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.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.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);
    }

    public onlineTable_result() {
    }

    public onlineTable_result(
      AccumuloException ouch1,
      AccumuloSecurityException ouch2,
      TableNotFoundException ouch3)
    {
      this();
      this.ouch1 = ouch1;
      this.ouch2 = ouch2;
      this.ouch3 = ouch3;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public onlineTable_result(onlineTable_result other) {
      if (other.isSetOuch1()) {
        this.ouch1 = new AccumuloException(other.ouch1);
      }
      if (other.isSetOuch2()) {
        this.ouch2 = new AccumuloSecurityException(other.ouch2);
      }
      if (other.isSetOuch3()) {
        this.ouch3 = new TableNotFoundException(other.ouch3);
      }
    }

    public onlineTable_result deepCopy() {
      return new onlineTable_result(this);
    }

    @Override
    public void clear() {
      this.ouch1 = null;
      this.ouch2 = null;
      this.ouch3 = null;
    }

    public AccumuloException getOuch1() {
      return this.ouch1;
    }

    public onlineTable_result setOuch1(AccumuloException ouch1) {
      this.ouch1 = ouch1;
      return this;
    }

    public void unsetOuch1() {
      this.ouch1 = null;
    }

    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch1() {
      return this.ouch1 != null;
    }

    public void setOuch1IsSet(boolean value) {
      if (!value) {
        this.ouch1 = null;
      }
    }

    public AccumuloSecurityException getOuch2() {
      return this.ouch2;
    }

    public onlineTable_result setOuch2(AccumuloSecurityException ouch2) {
      this.ouch2 = ouch2;
      return this;
    }

    public void unsetOuch2() {
      this.ouch2 = null;
    }

    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch2() {
      return this.ouch2 != null;
    }

    public void setOuch2IsSet(boolean value) {
      if (!value) {
        this.ouch2 = null;
      }
    }

    public TableNotFoundException getOuch3() {
      return this.ouch3;
    }

    public onlineTable_result setOuch3(TableNotFoundException ouch3) {
      this.ouch3 = ouch3;
      return this;
    }

    public void unsetOuch3() {
      this.ouch3 = null;
    }

    /** Returns true if field ouch3 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch3() {
      return this.ouch3 != null;
    }

    public void setOuch3IsSet(boolean value) {
      if (!value) {
        this.ouch3 = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case OUCH1:
        if (value == null) {
          unsetOuch1();
        } else {
          setOuch1((AccumuloException)value);
        }
        break;

      case OUCH2:
        if (value == null) {
          unsetOuch2();
        } else {
          setOuch2((AccumuloSecurityException)value);
        }
        break;

      case OUCH3:
        if (value == null) {
          unsetOuch3();
        } else {
          setOuch3((TableNotFoundException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case OUCH1:
        return getOuch1();

      case OUCH2:
        return getOuch2();

      case OUCH3:
        return getOuch3();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case OUCH1:
        return isSetOuch1();
      case OUCH2:
        return isSetOuch2();
      case OUCH3:
        return isSetOuch3();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof onlineTable_result)
        return this.equals((onlineTable_result)that);
      return false;
    }

    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();
      if (this_present_ouch1 || that_present_ouch1) {
        if (!(this_present_ouch1 && that_present_ouch1))
          return false;
        if (!this.ouch1.equals(that.ouch1))
          return false;
      }

      boolean this_present_ouch2 = true && this.isSetOuch2();
      boolean that_present_ouch2 = true && that.isSetOuch2();
      if (this_present_ouch2 || that_present_ouch2) {
        if (!(this_present_ouch2 && that_present_ouch2))
          return false;
        if (!this.ouch2.equals(that.ouch2))
          return false;
      }

      boolean this_present_ouch3 = true && this.isSetOuch3();
      boolean that_present_ouch3 = true && that.isSetOuch3();
      if (this_present_ouch3 || that_present_ouch3) {
        if (!(this_present_ouch3 && that_present_ouch3))
          return false;
        if (!this.ouch3.equals(that.ouch3))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
      if (isSetOuch1())
        hashCode = hashCode * 8191 + ouch1.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
      if (isSetOuch2())
        hashCode = hashCode * 8191 + ouch2.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
      if (isSetOuch3())
        hashCode = hashCode * 8191 + ouch3.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(onlineTable_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch1()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch2()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch3()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch3, other.ouch3);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("onlineTable_result(");
      boolean first = true;

      sb.append("ouch1:");
      if (this.ouch1 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch1);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch2:");
      if (this.ouch2 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch2);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch3:");
      if (this.ouch3 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch3);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class onlineTable_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public onlineTable_resultStandardScheme getScheme() {
        return new onlineTable_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // OUCH1
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch1 = new AccumuloException();
                struct.ouch1.read(iprot);
                struct.setOuch1IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OUCH2
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch2 = new AccumuloSecurityException();
                struct.ouch2.read(iprot);
                struct.setOuch2IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // OUCH3
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch3 = new TableNotFoundException();
                struct.ouch3.read(iprot);
                struct.setOuch3IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, onlineTable_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.ouch1 != null) {
          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
          struct.ouch1.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch2 != null) {
          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
          struct.ouch2.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch3 != null) {
          oprot.writeFieldBegin(OUCH3_FIELD_DESC);
          struct.ouch3.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class onlineTable_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public onlineTable_resultTupleScheme getScheme() {
        return new onlineTable_resultTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetOuch2()) {
          optionals.set(1);
        }
        if (struct.isSetOuch3()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetOuch1()) {
          struct.ouch1.write(oprot);
        }
        if (struct.isSetOuch2()) {
          struct.ouch2.write(oprot);
        }
        if (struct.isSetOuch3()) {
          struct.ouch3.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, onlineTable_result struct) throws org.apache.thrift.TException {
        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);
          struct.setOuch1IsSet(true);
        }
        if (incoming.get(1)) {
          struct.ouch2 = new AccumuloSecurityException();
          struct.ouch2.read(iprot);
          struct.setOuch2IsSet(true);
        }
        if (incoming.get(2)) {
          struct.ouch3 = new TableNotFoundException();
          struct.ouch3.read(iprot);
          struct.setOuch3IsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("removeConstraint_args");

    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField 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 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 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. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      LOGIN((short)1, "login"),
      TABLE_NAME((short)2, "tableName"),
      CONSTRAINT((short)3, "constraint");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // LOGIN
            return LOGIN;
          case 2: // TABLE_NAME
            return TABLE_NAME;
          case 3: // CONSTRAINT
            return CONSTRAINT;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __CONSTRAINT_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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 = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(removeConstraint_args.class, metaDataMap);
    }

    public removeConstraint_args() {
    }

    public removeConstraint_args(
      java.nio.ByteBuffer login,
      java.lang.String tableName,
      int constraint)
    {
      this();
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      this.tableName = tableName;
      this.constraint = constraint;
      setConstraintIsSet(true);
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public removeConstraint_args(removeConstraint_args other) {
      __isset_bitfield = other.__isset_bitfield;
      if (other.isSetLogin()) {
        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
      }
      if (other.isSetTableName()) {
        this.tableName = other.tableName;
      }
      this.constraint = other.constraint;
    }

    public removeConstraint_args deepCopy() {
      return new removeConstraint_args(this);
    }

    @Override
    public void clear() {
      this.login = null;
      this.tableName = null;
      setConstraintIsSet(false);
      this.constraint = 0;
    }

    public byte[] getLogin() {
      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
      return login == null ? null : login.array();
    }

    public java.nio.ByteBuffer bufferForLogin() {
      return org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    public removeConstraint_args setLogin(byte[] login) {
      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
      return this;
    }

    public removeConstraint_args setLogin(java.nio.ByteBuffer login) {
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      return this;
    }

    public void unsetLogin() {
      this.login = null;
    }

    /** Returns true if field login is set (has been assigned a value) and false otherwise */
    public boolean isSetLogin() {
      return this.login != null;
    }

    public void setLoginIsSet(boolean value) {
      if (!value) {
        this.login = null;
      }
    }

    public java.lang.String getTableName() {
      return this.tableName;
    }

    public removeConstraint_args setTableName(java.lang.String tableName) {
      this.tableName = tableName;
      return this;
    }

    public void unsetTableName() {
      this.tableName = null;
    }

    /** Returns true if field tableName is set (has been assigned a value) and false otherwise */
    public boolean isSetTableName() {
      return this.tableName != null;
    }

    public void setTableNameIsSet(boolean value) {
      if (!value) {
        this.tableName = null;
      }
    }

    public int getConstraint() {
      return this.constraint;
    }

    public removeConstraint_args setConstraint(int constraint) {
      this.constraint = constraint;
      setConstraintIsSet(true);
      return this;
    }

    public void unsetConstraint() {
      __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 org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __CONSTRAINT_ISSET_ID);
    }

    public void setConstraintIsSet(boolean value) {
      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __CONSTRAINT_ISSET_ID, value);
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case LOGIN:
        if (value == null) {
          unsetLogin();
        } else {
          if (value instanceof byte[]) {
            setLogin((byte[])value);
          } else {
            setLogin((java.nio.ByteBuffer)value);
          }
        }
        break;

      case TABLE_NAME:
        if (value == null) {
          unsetTableName();
        } else {
          setTableName((java.lang.String)value);
        }
        break;

      case CONSTRAINT:
        if (value == null) {
          unsetConstraint();
        } else {
          setConstraint((java.lang.Integer)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case LOGIN:
        return getLogin();

      case TABLE_NAME:
        return getTableName();

      case CONSTRAINT:
        return getConstraint();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case LOGIN:
        return isSetLogin();
      case TABLE_NAME:
        return isSetTableName();
      case CONSTRAINT:
        return isSetConstraint();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof removeConstraint_args)
        return this.equals((removeConstraint_args)that);
      return false;
    }

    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();
      if (this_present_login || that_present_login) {
        if (!(this_present_login && that_present_login))
          return false;
        if (!this.login.equals(that.login))
          return false;
      }

      boolean this_present_tableName = true && this.isSetTableName();
      boolean that_present_tableName = true && that.isSetTableName();
      if (this_present_tableName || that_present_tableName) {
        if (!(this_present_tableName && that_present_tableName))
          return false;
        if (!this.tableName.equals(that.tableName))
          return false;
      }

      boolean this_present_constraint = true;
      boolean that_present_constraint = true;
      if (this_present_constraint || that_present_constraint) {
        if (!(this_present_constraint && that_present_constraint))
          return false;
        if (this.constraint != that.constraint)
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
      if (isSetLogin())
        hashCode = hashCode * 8191 + login.hashCode();

      hashCode = hashCode * 8191 + ((isSetTableName()) ? 131071 : 524287);
      if (isSetTableName())
        hashCode = hashCode * 8191 + tableName.hashCode();

      hashCode = hashCode * 8191 + constraint;

      return hashCode;
    }

    @Override
    public int compareTo(removeConstraint_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLogin()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetTableName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.tableName, other.tableName);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetConstraint()).compareTo(other.isSetConstraint());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetConstraint()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.constraint, other.constraint);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("removeConstraint_args(");
      boolean first = true;

      sb.append("login:");
      if (this.login == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.login, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("tableName:");
      if (this.tableName == null) {
        sb.append("null");
      } else {
        sb.append(this.tableName);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("constraint:");
      sb.append(this.constraint);
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, 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;
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class removeConstraint_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public removeConstraint_argsStandardScheme getScheme() {
        return new removeConstraint_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // LOGIN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.login = iprot.readBinary();
                struct.setLoginIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // TABLE_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.tableName = iprot.readString();
                struct.setTableNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // CONSTRAINT
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.constraint = iprot.readI32();
                struct.setConstraintIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, removeConstraint_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.login != null) {
          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
          oprot.writeBinary(struct.login);
          oprot.writeFieldEnd();
        }
        if (struct.tableName != null) {
          oprot.writeFieldBegin(TABLE_NAME_FIELD_DESC);
          oprot.writeString(struct.tableName);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldBegin(CONSTRAINT_FIELD_DESC);
        oprot.writeI32(struct.constraint);
        oprot.writeFieldEnd();
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    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 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 {
        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);
        }
        if (struct.isSetTableName()) {
          optionals.set(1);
        }
        if (struct.isSetConstraint()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetLogin()) {
          oprot.writeBinary(struct.login);
        }
        if (struct.isSetTableName()) {
          oprot.writeString(struct.tableName);
        }
        if (struct.isSetConstraint()) {
          oprot.writeI32(struct.constraint);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, removeConstraint_args struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.tableName = iprot.readString();
          struct.setTableNameIsSet(true);
        }
        if (incoming.get(2)) {
          struct.constraint = iprot.readI32();
          struct.setConstraintIsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("removeConstraint_result");

    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField OUCH3_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch3", org.apache.thrift.protocol.TType.STRUCT, (short)3);

    private static final org.apache.thrift.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
    public TableNotFoundException ouch3; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      OUCH1((short)1, "ouch1"),
      OUCH2((short)2, "ouch2"),
      OUCH3((short)3, "ouch3");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // OUCH1
            return OUCH1;
          case 2: // OUCH2
            return OUCH2;
          case 3: // OUCH3
            return OUCH3;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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.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.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);
    }

    public removeConstraint_result() {
    }

    public removeConstraint_result(
      AccumuloException ouch1,
      AccumuloSecurityException ouch2,
      TableNotFoundException ouch3)
    {
      this();
      this.ouch1 = ouch1;
      this.ouch2 = ouch2;
      this.ouch3 = ouch3;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public removeConstraint_result(removeConstraint_result other) {
      if (other.isSetOuch1()) {
        this.ouch1 = new AccumuloException(other.ouch1);
      }
      if (other.isSetOuch2()) {
        this.ouch2 = new AccumuloSecurityException(other.ouch2);
      }
      if (other.isSetOuch3()) {
        this.ouch3 = new TableNotFoundException(other.ouch3);
      }
    }

    public removeConstraint_result deepCopy() {
      return new removeConstraint_result(this);
    }

    @Override
    public void clear() {
      this.ouch1 = null;
      this.ouch2 = null;
      this.ouch3 = null;
    }

    public AccumuloException getOuch1() {
      return this.ouch1;
    }

    public removeConstraint_result setOuch1(AccumuloException ouch1) {
      this.ouch1 = ouch1;
      return this;
    }

    public void unsetOuch1() {
      this.ouch1 = null;
    }

    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch1() {
      return this.ouch1 != null;
    }

    public void setOuch1IsSet(boolean value) {
      if (!value) {
        this.ouch1 = null;
      }
    }

    public AccumuloSecurityException getOuch2() {
      return this.ouch2;
    }

    public removeConstraint_result setOuch2(AccumuloSecurityException ouch2) {
      this.ouch2 = ouch2;
      return this;
    }

    public void unsetOuch2() {
      this.ouch2 = null;
    }

    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch2() {
      return this.ouch2 != null;
    }

    public void setOuch2IsSet(boolean value) {
      if (!value) {
        this.ouch2 = null;
      }
    }

    public TableNotFoundException getOuch3() {
      return this.ouch3;
    }

    public removeConstraint_result setOuch3(TableNotFoundException ouch3) {
      this.ouch3 = ouch3;
      return this;
    }

    public void unsetOuch3() {
      this.ouch3 = null;
    }

    /** Returns true if field ouch3 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch3() {
      return this.ouch3 != null;
    }

    public void setOuch3IsSet(boolean value) {
      if (!value) {
        this.ouch3 = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case OUCH1:
        if (value == null) {
          unsetOuch1();
        } else {
          setOuch1((AccumuloException)value);
        }
        break;

      case OUCH2:
        if (value == null) {
          unsetOuch2();
        } else {
          setOuch2((AccumuloSecurityException)value);
        }
        break;

      case OUCH3:
        if (value == null) {
          unsetOuch3();
        } else {
          setOuch3((TableNotFoundException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case OUCH1:
        return getOuch1();

      case OUCH2:
        return getOuch2();

      case OUCH3:
        return getOuch3();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case OUCH1:
        return isSetOuch1();
      case OUCH2:
        return isSetOuch2();
      case OUCH3:
        return isSetOuch3();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof removeConstraint_result)
        return this.equals((removeConstraint_result)that);
      return false;
    }

    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();
      if (this_present_ouch1 || that_present_ouch1) {
        if (!(this_present_ouch1 && that_present_ouch1))
          return false;
        if (!this.ouch1.equals(that.ouch1))
          return false;
      }

      boolean this_present_ouch2 = true && this.isSetOuch2();
      boolean that_present_ouch2 = true && that.isSetOuch2();
      if (this_present_ouch2 || that_present_ouch2) {
        if (!(this_present_ouch2 && that_present_ouch2))
          return false;
        if (!this.ouch2.equals(that.ouch2))
          return false;
      }

      boolean this_present_ouch3 = true && this.isSetOuch3();
      boolean that_present_ouch3 = true && that.isSetOuch3();
      if (this_present_ouch3 || that_present_ouch3) {
        if (!(this_present_ouch3 && that_present_ouch3))
          return false;
        if (!this.ouch3.equals(that.ouch3))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
      if (isSetOuch1())
        hashCode = hashCode * 8191 + ouch1.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
      if (isSetOuch2())
        hashCode = hashCode * 8191 + ouch2.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
      if (isSetOuch3())
        hashCode = hashCode * 8191 + ouch3.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(removeConstraint_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch1()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch2()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch3()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch3, other.ouch3);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("removeConstraint_result(");
      boolean first = true;

      sb.append("ouch1:");
      if (this.ouch1 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch1);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch2:");
      if (this.ouch2 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch2);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch3:");
      if (this.ouch3 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch3);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class removeConstraint_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public removeConstraint_resultStandardScheme getScheme() {
        return new removeConstraint_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // OUCH1
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch1 = new AccumuloException();
                struct.ouch1.read(iprot);
                struct.setOuch1IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OUCH2
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch2 = new AccumuloSecurityException();
                struct.ouch2.read(iprot);
                struct.setOuch2IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // OUCH3
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch3 = new TableNotFoundException();
                struct.ouch3.read(iprot);
                struct.setOuch3IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, removeConstraint_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.ouch1 != null) {
          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
          struct.ouch1.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch2 != null) {
          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
          struct.ouch2.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch3 != null) {
          oprot.writeFieldBegin(OUCH3_FIELD_DESC);
          struct.ouch3.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class removeConstraint_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public removeConstraint_resultTupleScheme getScheme() {
        return new removeConstraint_resultTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetOuch2()) {
          optionals.set(1);
        }
        if (struct.isSetOuch3()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetOuch1()) {
          struct.ouch1.write(oprot);
        }
        if (struct.isSetOuch2()) {
          struct.ouch2.write(oprot);
        }
        if (struct.isSetOuch3()) {
          struct.ouch3.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, removeConstraint_result struct) throws org.apache.thrift.TException {
        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);
          struct.setOuch1IsSet(true);
        }
        if (incoming.get(1)) {
          struct.ouch2 = new AccumuloSecurityException();
          struct.ouch2.read(iprot);
          struct.setOuch2IsSet(true);
        }
        if (incoming.get(2)) {
          struct.ouch3 = new TableNotFoundException();
          struct.ouch3.read(iprot);
          struct.setOuch3IsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("removeIterator_args");

    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField 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 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 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 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 {
      LOGIN((short)1, "login"),
      TABLE_NAME((short)2, "tableName"),
      ITER_NAME((short)3, "iterName"),
      SCOPES((short)4, "scopes");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // LOGIN
            return LOGIN;
          case 2: // TABLE_NAME
            return TABLE_NAME;
          case 3: // ITER_NAME
            return ITER_NAME;
          case 4: // SCOPES
            return SCOPES;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.ITER_NAME, new org.apache.thrift.meta_data.FieldMetaData("iterName", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.SCOPES, new org.apache.thrift.meta_data.FieldMetaData("scopes", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.SetMetaData(org.apache.thrift.protocol.TType.SET, 
              new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, IteratorScope.class))));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(removeIterator_args.class, metaDataMap);
    }

    public removeIterator_args() {
    }

    public removeIterator_args(
      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);
      this.tableName = tableName;
      this.iterName = iterName;
      this.scopes = scopes;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public removeIterator_args(removeIterator_args other) {
      if (other.isSetLogin()) {
        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
      }
      if (other.isSetTableName()) {
        this.tableName = other.tableName;
      }
      if (other.isSetIterName()) {
        this.iterName = other.iterName;
      }
      if (other.isSetScopes()) {
        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);
        }
        this.scopes = __this__scopes;
      }
    }

    public removeIterator_args deepCopy() {
      return new removeIterator_args(this);
    }

    @Override
    public void clear() {
      this.login = null;
      this.tableName = null;
      this.iterName = null;
      this.scopes = null;
    }

    public byte[] getLogin() {
      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
      return login == null ? null : login.array();
    }

    public java.nio.ByteBuffer bufferForLogin() {
      return org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    public removeIterator_args setLogin(byte[] login) {
      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
      return this;
    }

    public removeIterator_args setLogin(java.nio.ByteBuffer login) {
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      return this;
    }

    public void unsetLogin() {
      this.login = null;
    }

    /** Returns true if field login is set (has been assigned a value) and false otherwise */
    public boolean isSetLogin() {
      return this.login != null;
    }

    public void setLoginIsSet(boolean value) {
      if (!value) {
        this.login = null;
      }
    }

    public java.lang.String getTableName() {
      return this.tableName;
    }

    public removeIterator_args setTableName(java.lang.String tableName) {
      this.tableName = tableName;
      return this;
    }

    public void unsetTableName() {
      this.tableName = null;
    }

    /** Returns true if field tableName is set (has been assigned a value) and false otherwise */
    public boolean isSetTableName() {
      return this.tableName != null;
    }

    public void setTableNameIsSet(boolean value) {
      if (!value) {
        this.tableName = null;
      }
    }

    public java.lang.String getIterName() {
      return this.iterName;
    }

    public removeIterator_args setIterName(java.lang.String iterName) {
      this.iterName = iterName;
      return this;
    }

    public void unsetIterName() {
      this.iterName = null;
    }

    /** Returns true if field iterName is set (has been assigned a value) and false otherwise */
    public boolean isSetIterName() {
      return this.iterName != null;
    }

    public void setIterNameIsSet(boolean value) {
      if (!value) {
        this.iterName = null;
      }
    }

    public int getScopesSize() {
      return (this.scopes == null) ? 0 : this.scopes.size();
    }

    public java.util.Iterator<IteratorScope> getScopesIterator() {
      return (this.scopes == null) ? null : this.scopes.iterator();
    }

    public void addToScopes(IteratorScope elem) {
      if (this.scopes == null) {
        this.scopes = new java.util.HashSet<IteratorScope>();
      }
      this.scopes.add(elem);
    }

    public java.util.Set<IteratorScope> getScopes() {
      return this.scopes;
    }

    public removeIterator_args setScopes(java.util.Set<IteratorScope> scopes) {
      this.scopes = scopes;
      return this;
    }

    public void unsetScopes() {
      this.scopes = null;
    }

    /** Returns true if field scopes is set (has been assigned a value) and false otherwise */
    public boolean isSetScopes() {
      return this.scopes != null;
    }

    public void setScopesIsSet(boolean value) {
      if (!value) {
        this.scopes = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case LOGIN:
        if (value == null) {
          unsetLogin();
        } else {
          if (value instanceof byte[]) {
            setLogin((byte[])value);
          } else {
            setLogin((java.nio.ByteBuffer)value);
          }
        }
        break;

      case TABLE_NAME:
        if (value == null) {
          unsetTableName();
        } else {
          setTableName((java.lang.String)value);
        }
        break;

      case ITER_NAME:
        if (value == null) {
          unsetIterName();
        } else {
          setIterName((java.lang.String)value);
        }
        break;

      case SCOPES:
        if (value == null) {
          unsetScopes();
        } else {
          setScopes((java.util.Set<IteratorScope>)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case LOGIN:
        return getLogin();

      case TABLE_NAME:
        return getTableName();

      case ITER_NAME:
        return getIterName();

      case SCOPES:
        return getScopes();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case LOGIN:
        return isSetLogin();
      case TABLE_NAME:
        return isSetTableName();
      case ITER_NAME:
        return isSetIterName();
      case SCOPES:
        return isSetScopes();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof removeIterator_args)
        return this.equals((removeIterator_args)that);
      return false;
    }

    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();
      if (this_present_login || that_present_login) {
        if (!(this_present_login && that_present_login))
          return false;
        if (!this.login.equals(that.login))
          return false;
      }

      boolean this_present_tableName = true && this.isSetTableName();
      boolean that_present_tableName = true && that.isSetTableName();
      if (this_present_tableName || that_present_tableName) {
        if (!(this_present_tableName && that_present_tableName))
          return false;
        if (!this.tableName.equals(that.tableName))
          return false;
      }

      boolean this_present_iterName = true && this.isSetIterName();
      boolean that_present_iterName = true && that.isSetIterName();
      if (this_present_iterName || that_present_iterName) {
        if (!(this_present_iterName && that_present_iterName))
          return false;
        if (!this.iterName.equals(that.iterName))
          return false;
      }

      boolean this_present_scopes = true && this.isSetScopes();
      boolean that_present_scopes = true && that.isSetScopes();
      if (this_present_scopes || that_present_scopes) {
        if (!(this_present_scopes && that_present_scopes))
          return false;
        if (!this.scopes.equals(that.scopes))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
      if (isSetLogin())
        hashCode = hashCode * 8191 + login.hashCode();

      hashCode = hashCode * 8191 + ((isSetTableName()) ? 131071 : 524287);
      if (isSetTableName())
        hashCode = hashCode * 8191 + tableName.hashCode();

      hashCode = hashCode * 8191 + ((isSetIterName()) ? 131071 : 524287);
      if (isSetIterName())
        hashCode = hashCode * 8191 + iterName.hashCode();

      hashCode = hashCode * 8191 + ((isSetScopes()) ? 131071 : 524287);
      if (isSetScopes())
        hashCode = hashCode * 8191 + scopes.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(removeIterator_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLogin()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetTableName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.tableName, other.tableName);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetIterName()).compareTo(other.isSetIterName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIterName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.iterName, other.iterName);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetScopes()).compareTo(other.isSetScopes());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetScopes()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.scopes, other.scopes);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("removeIterator_args(");
      boolean first = true;

      sb.append("login:");
      if (this.login == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.login, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("tableName:");
      if (this.tableName == null) {
        sb.append("null");
      } else {
        sb.append(this.tableName);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("iterName:");
      if (this.iterName == null) {
        sb.append("null");
      } else {
        sb.append(this.iterName);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("scopes:");
      if (this.scopes == null) {
        sb.append("null");
      } else {
        sb.append(this.scopes);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class removeIterator_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public removeIterator_argsStandardScheme getScheme() {
        return new removeIterator_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // LOGIN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.login = iprot.readBinary();
                struct.setLoginIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // TABLE_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.tableName = iprot.readString();
                struct.setTableNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ITER_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.iterName = iprot.readString();
                struct.setIterNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // SCOPES
              if (schemeField.type == org.apache.thrift.protocol.TType.SET) {
                {
                  org.apache.thrift.protocol.TSet _set320 = iprot.readSetBegin();
                  struct.scopes = new java.util.HashSet<IteratorScope>(2*_set320.size);
                  IteratorScope _elem321;
                  for (int _i322 = 0; _i322 < _set320.size; ++_i322)
                  {
                    _elem321 = org.apache.accumulo.proxy.thrift.IteratorScope.findByValue(iprot.readI32());
                    struct.scopes.add(_elem321);
                  }
                  iprot.readSetEnd();
                }
                struct.setScopesIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, removeIterator_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.login != null) {
          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
          oprot.writeBinary(struct.login);
          oprot.writeFieldEnd();
        }
        if (struct.tableName != null) {
          oprot.writeFieldBegin(TABLE_NAME_FIELD_DESC);
          oprot.writeString(struct.tableName);
          oprot.writeFieldEnd();
        }
        if (struct.iterName != null) {
          oprot.writeFieldBegin(ITER_NAME_FIELD_DESC);
          oprot.writeString(struct.iterName);
          oprot.writeFieldEnd();
        }
        if (struct.scopes != null) {
          oprot.writeFieldBegin(SCOPES_FIELD_DESC);
          {
            oprot.writeSetBegin(new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.I32, struct.scopes.size()));
            for (IteratorScope _iter323 : struct.scopes)
            {
              oprot.writeI32(_iter323.getValue());
            }
            oprot.writeSetEnd();
          }
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    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 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 {
        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);
        }
        if (struct.isSetTableName()) {
          optionals.set(1);
        }
        if (struct.isSetIterName()) {
          optionals.set(2);
        }
        if (struct.isSetScopes()) {
          optionals.set(3);
        }
        oprot.writeBitSet(optionals, 4);
        if (struct.isSetLogin()) {
          oprot.writeBinary(struct.login);
        }
        if (struct.isSetTableName()) {
          oprot.writeString(struct.tableName);
        }
        if (struct.isSetIterName()) {
          oprot.writeString(struct.iterName);
        }
        if (struct.isSetScopes()) {
          {
            oprot.writeI32(struct.scopes.size());
            for (IteratorScope _iter324 : struct.scopes)
            {
              oprot.writeI32(_iter324.getValue());
            }
          }
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, removeIterator_args struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.tableName = iprot.readString();
          struct.setTableNameIsSet(true);
        }
        if (incoming.get(2)) {
          struct.iterName = iprot.readString();
          struct.setIterNameIsSet(true);
        }
        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 java.util.HashSet<IteratorScope>(2*_set325.size);
            IteratorScope _elem326;
            for (int _i327 = 0; _i327 < _set325.size; ++_i327)
            {
              _elem326 = org.apache.accumulo.proxy.thrift.IteratorScope.findByValue(iprot.readI32());
              struct.scopes.add(_elem326);
            }
          }
          struct.setScopesIsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("removeIterator_result");

    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField OUCH3_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch3", org.apache.thrift.protocol.TType.STRUCT, (short)3);

    private static final org.apache.thrift.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
    public TableNotFoundException ouch3; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      OUCH1((short)1, "ouch1"),
      OUCH2((short)2, "ouch2"),
      OUCH3((short)3, "ouch3");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // OUCH1
            return OUCH1;
          case 2: // OUCH2
            return OUCH2;
          case 3: // OUCH3
            return OUCH3;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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.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.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);
    }

    public removeIterator_result() {
    }

    public removeIterator_result(
      AccumuloException ouch1,
      AccumuloSecurityException ouch2,
      TableNotFoundException ouch3)
    {
      this();
      this.ouch1 = ouch1;
      this.ouch2 = ouch2;
      this.ouch3 = ouch3;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public removeIterator_result(removeIterator_result other) {
      if (other.isSetOuch1()) {
        this.ouch1 = new AccumuloException(other.ouch1);
      }
      if (other.isSetOuch2()) {
        this.ouch2 = new AccumuloSecurityException(other.ouch2);
      }
      if (other.isSetOuch3()) {
        this.ouch3 = new TableNotFoundException(other.ouch3);
      }
    }

    public removeIterator_result deepCopy() {
      return new removeIterator_result(this);
    }

    @Override
    public void clear() {
      this.ouch1 = null;
      this.ouch2 = null;
      this.ouch3 = null;
    }

    public AccumuloException getOuch1() {
      return this.ouch1;
    }

    public removeIterator_result setOuch1(AccumuloException ouch1) {
      this.ouch1 = ouch1;
      return this;
    }

    public void unsetOuch1() {
      this.ouch1 = null;
    }

    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch1() {
      return this.ouch1 != null;
    }

    public void setOuch1IsSet(boolean value) {
      if (!value) {
        this.ouch1 = null;
      }
    }

    public AccumuloSecurityException getOuch2() {
      return this.ouch2;
    }

    public removeIterator_result setOuch2(AccumuloSecurityException ouch2) {
      this.ouch2 = ouch2;
      return this;
    }

    public void unsetOuch2() {
      this.ouch2 = null;
    }

    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch2() {
      return this.ouch2 != null;
    }

    public void setOuch2IsSet(boolean value) {
      if (!value) {
        this.ouch2 = null;
      }
    }

    public TableNotFoundException getOuch3() {
      return this.ouch3;
    }

    public removeIterator_result setOuch3(TableNotFoundException ouch3) {
      this.ouch3 = ouch3;
      return this;
    }

    public void unsetOuch3() {
      this.ouch3 = null;
    }

    /** Returns true if field ouch3 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch3() {
      return this.ouch3 != null;
    }

    public void setOuch3IsSet(boolean value) {
      if (!value) {
        this.ouch3 = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case OUCH1:
        if (value == null) {
          unsetOuch1();
        } else {
          setOuch1((AccumuloException)value);
        }
        break;

      case OUCH2:
        if (value == null) {
          unsetOuch2();
        } else {
          setOuch2((AccumuloSecurityException)value);
        }
        break;

      case OUCH3:
        if (value == null) {
          unsetOuch3();
        } else {
          setOuch3((TableNotFoundException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case OUCH1:
        return getOuch1();

      case OUCH2:
        return getOuch2();

      case OUCH3:
        return getOuch3();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case OUCH1:
        return isSetOuch1();
      case OUCH2:
        return isSetOuch2();
      case OUCH3:
        return isSetOuch3();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof removeIterator_result)
        return this.equals((removeIterator_result)that);
      return false;
    }

    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();
      if (this_present_ouch1 || that_present_ouch1) {
        if (!(this_present_ouch1 && that_present_ouch1))
          return false;
        if (!this.ouch1.equals(that.ouch1))
          return false;
      }

      boolean this_present_ouch2 = true && this.isSetOuch2();
      boolean that_present_ouch2 = true && that.isSetOuch2();
      if (this_present_ouch2 || that_present_ouch2) {
        if (!(this_present_ouch2 && that_present_ouch2))
          return false;
        if (!this.ouch2.equals(that.ouch2))
          return false;
      }

      boolean this_present_ouch3 = true && this.isSetOuch3();
      boolean that_present_ouch3 = true && that.isSetOuch3();
      if (this_present_ouch3 || that_present_ouch3) {
        if (!(this_present_ouch3 && that_present_ouch3))
          return false;
        if (!this.ouch3.equals(that.ouch3))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
      if (isSetOuch1())
        hashCode = hashCode * 8191 + ouch1.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
      if (isSetOuch2())
        hashCode = hashCode * 8191 + ouch2.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
      if (isSetOuch3())
        hashCode = hashCode * 8191 + ouch3.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(removeIterator_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch1()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch2()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch3()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch3, other.ouch3);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("removeIterator_result(");
      boolean first = true;

      sb.append("ouch1:");
      if (this.ouch1 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch1);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch2:");
      if (this.ouch2 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch2);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch3:");
      if (this.ouch3 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch3);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class removeIterator_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public removeIterator_resultStandardScheme getScheme() {
        return new removeIterator_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // OUCH1
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch1 = new AccumuloException();
                struct.ouch1.read(iprot);
                struct.setOuch1IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OUCH2
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch2 = new AccumuloSecurityException();
                struct.ouch2.read(iprot);
                struct.setOuch2IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // OUCH3
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch3 = new TableNotFoundException();
                struct.ouch3.read(iprot);
                struct.setOuch3IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, removeIterator_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.ouch1 != null) {
          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
          struct.ouch1.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch2 != null) {
          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
          struct.ouch2.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch3 != null) {
          oprot.writeFieldBegin(OUCH3_FIELD_DESC);
          struct.ouch3.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class removeIterator_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public removeIterator_resultTupleScheme getScheme() {
        return new removeIterator_resultTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetOuch2()) {
          optionals.set(1);
        }
        if (struct.isSetOuch3()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetOuch1()) {
          struct.ouch1.write(oprot);
        }
        if (struct.isSetOuch2()) {
          struct.ouch2.write(oprot);
        }
        if (struct.isSetOuch3()) {
          struct.ouch3.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, removeIterator_result struct) throws org.apache.thrift.TException {
        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);
          struct.setOuch1IsSet(true);
        }
        if (incoming.get(1)) {
          struct.ouch2 = new AccumuloSecurityException();
          struct.ouch2.read(iprot);
          struct.setOuch2IsSet(true);
        }
        if (incoming.get(2)) {
          struct.ouch3 = new TableNotFoundException();
          struct.ouch3.read(iprot);
          struct.setOuch3IsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("removeTableProperty_args");

    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField 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 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 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 {
      LOGIN((short)1, "login"),
      TABLE_NAME((short)2, "tableName"),
      PROPERTY((short)3, "property");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // LOGIN
            return LOGIN;
          case 2: // TABLE_NAME
            return TABLE_NAME;
          case 3: // PROPERTY
            return PROPERTY;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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 = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(removeTableProperty_args.class, metaDataMap);
    }

    public removeTableProperty_args() {
    }

    public removeTableProperty_args(
      java.nio.ByteBuffer login,
      java.lang.String tableName,
      java.lang.String property)
    {
      this();
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      this.tableName = tableName;
      this.property = property;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public removeTableProperty_args(removeTableProperty_args other) {
      if (other.isSetLogin()) {
        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
      }
      if (other.isSetTableName()) {
        this.tableName = other.tableName;
      }
      if (other.isSetProperty()) {
        this.property = other.property;
      }
    }

    public removeTableProperty_args deepCopy() {
      return new removeTableProperty_args(this);
    }

    @Override
    public void clear() {
      this.login = null;
      this.tableName = null;
      this.property = null;
    }

    public byte[] getLogin() {
      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
      return login == null ? null : login.array();
    }

    public java.nio.ByteBuffer bufferForLogin() {
      return org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    public removeTableProperty_args setLogin(byte[] login) {
      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
      return this;
    }

    public removeTableProperty_args setLogin(java.nio.ByteBuffer login) {
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      return this;
    }

    public void unsetLogin() {
      this.login = null;
    }

    /** Returns true if field login is set (has been assigned a value) and false otherwise */
    public boolean isSetLogin() {
      return this.login != null;
    }

    public void setLoginIsSet(boolean value) {
      if (!value) {
        this.login = null;
      }
    }

    public java.lang.String getTableName() {
      return this.tableName;
    }

    public removeTableProperty_args setTableName(java.lang.String tableName) {
      this.tableName = tableName;
      return this;
    }

    public void unsetTableName() {
      this.tableName = null;
    }

    /** Returns true if field tableName is set (has been assigned a value) and false otherwise */
    public boolean isSetTableName() {
      return this.tableName != null;
    }

    public void setTableNameIsSet(boolean value) {
      if (!value) {
        this.tableName = null;
      }
    }

    public java.lang.String getProperty() {
      return this.property;
    }

    public removeTableProperty_args setProperty(java.lang.String property) {
      this.property = property;
      return this;
    }

    public void unsetProperty() {
      this.property = null;
    }

    /** Returns true if field property is set (has been assigned a value) and false otherwise */
    public boolean isSetProperty() {
      return this.property != null;
    }

    public void setPropertyIsSet(boolean value) {
      if (!value) {
        this.property = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case LOGIN:
        if (value == null) {
          unsetLogin();
        } else {
          if (value instanceof byte[]) {
            setLogin((byte[])value);
          } else {
            setLogin((java.nio.ByteBuffer)value);
          }
        }
        break;

      case TABLE_NAME:
        if (value == null) {
          unsetTableName();
        } else {
          setTableName((java.lang.String)value);
        }
        break;

      case PROPERTY:
        if (value == null) {
          unsetProperty();
        } else {
          setProperty((java.lang.String)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case LOGIN:
        return getLogin();

      case TABLE_NAME:
        return getTableName();

      case PROPERTY:
        return getProperty();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case LOGIN:
        return isSetLogin();
      case TABLE_NAME:
        return isSetTableName();
      case PROPERTY:
        return isSetProperty();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof removeTableProperty_args)
        return this.equals((removeTableProperty_args)that);
      return false;
    }

    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();
      if (this_present_login || that_present_login) {
        if (!(this_present_login && that_present_login))
          return false;
        if (!this.login.equals(that.login))
          return false;
      }

      boolean this_present_tableName = true && this.isSetTableName();
      boolean that_present_tableName = true && that.isSetTableName();
      if (this_present_tableName || that_present_tableName) {
        if (!(this_present_tableName && that_present_tableName))
          return false;
        if (!this.tableName.equals(that.tableName))
          return false;
      }

      boolean this_present_property = true && this.isSetProperty();
      boolean that_present_property = true && that.isSetProperty();
      if (this_present_property || that_present_property) {
        if (!(this_present_property && that_present_property))
          return false;
        if (!this.property.equals(that.property))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
      if (isSetLogin())
        hashCode = hashCode * 8191 + login.hashCode();

      hashCode = hashCode * 8191 + ((isSetTableName()) ? 131071 : 524287);
      if (isSetTableName())
        hashCode = hashCode * 8191 + tableName.hashCode();

      hashCode = hashCode * 8191 + ((isSetProperty()) ? 131071 : 524287);
      if (isSetProperty())
        hashCode = hashCode * 8191 + property.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(removeTableProperty_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLogin()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetTableName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.tableName, other.tableName);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetProperty()).compareTo(other.isSetProperty());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetProperty()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.property, other.property);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("removeTableProperty_args(");
      boolean first = true;

      sb.append("login:");
      if (this.login == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.login, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("tableName:");
      if (this.tableName == null) {
        sb.append("null");
      } else {
        sb.append(this.tableName);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("property:");
      if (this.property == null) {
        sb.append("null");
      } else {
        sb.append(this.property);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class removeTableProperty_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public removeTableProperty_argsStandardScheme getScheme() {
        return new removeTableProperty_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // LOGIN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.login = iprot.readBinary();
                struct.setLoginIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // TABLE_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.tableName = iprot.readString();
                struct.setTableNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // PROPERTY
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.property = iprot.readString();
                struct.setPropertyIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, removeTableProperty_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.login != null) {
          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
          oprot.writeBinary(struct.login);
          oprot.writeFieldEnd();
        }
        if (struct.tableName != null) {
          oprot.writeFieldBegin(TABLE_NAME_FIELD_DESC);
          oprot.writeString(struct.tableName);
          oprot.writeFieldEnd();
        }
        if (struct.property != null) {
          oprot.writeFieldBegin(PROPERTY_FIELD_DESC);
          oprot.writeString(struct.property);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    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 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 {
        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);
        }
        if (struct.isSetTableName()) {
          optionals.set(1);
        }
        if (struct.isSetProperty()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetLogin()) {
          oprot.writeBinary(struct.login);
        }
        if (struct.isSetTableName()) {
          oprot.writeString(struct.tableName);
        }
        if (struct.isSetProperty()) {
          oprot.writeString(struct.property);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, removeTableProperty_args struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.tableName = iprot.readString();
          struct.setTableNameIsSet(true);
        }
        if (incoming.get(2)) {
          struct.property = iprot.readString();
          struct.setPropertyIsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("removeTableProperty_result");

    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField OUCH3_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch3", org.apache.thrift.protocol.TType.STRUCT, (short)3);

    private static final org.apache.thrift.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
    public TableNotFoundException ouch3; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      OUCH1((short)1, "ouch1"),
      OUCH2((short)2, "ouch2"),
      OUCH3((short)3, "ouch3");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // OUCH1
            return OUCH1;
          case 2: // OUCH2
            return OUCH2;
          case 3: // OUCH3
            return OUCH3;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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.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.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);
    }

    public removeTableProperty_result() {
    }

    public removeTableProperty_result(
      AccumuloException ouch1,
      AccumuloSecurityException ouch2,
      TableNotFoundException ouch3)
    {
      this();
      this.ouch1 = ouch1;
      this.ouch2 = ouch2;
      this.ouch3 = ouch3;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public removeTableProperty_result(removeTableProperty_result other) {
      if (other.isSetOuch1()) {
        this.ouch1 = new AccumuloException(other.ouch1);
      }
      if (other.isSetOuch2()) {
        this.ouch2 = new AccumuloSecurityException(other.ouch2);
      }
      if (other.isSetOuch3()) {
        this.ouch3 = new TableNotFoundException(other.ouch3);
      }
    }

    public removeTableProperty_result deepCopy() {
      return new removeTableProperty_result(this);
    }

    @Override
    public void clear() {
      this.ouch1 = null;
      this.ouch2 = null;
      this.ouch3 = null;
    }

    public AccumuloException getOuch1() {
      return this.ouch1;
    }

    public removeTableProperty_result setOuch1(AccumuloException ouch1) {
      this.ouch1 = ouch1;
      return this;
    }

    public void unsetOuch1() {
      this.ouch1 = null;
    }

    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch1() {
      return this.ouch1 != null;
    }

    public void setOuch1IsSet(boolean value) {
      if (!value) {
        this.ouch1 = null;
      }
    }

    public AccumuloSecurityException getOuch2() {
      return this.ouch2;
    }

    public removeTableProperty_result setOuch2(AccumuloSecurityException ouch2) {
      this.ouch2 = ouch2;
      return this;
    }

    public void unsetOuch2() {
      this.ouch2 = null;
    }

    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch2() {
      return this.ouch2 != null;
    }

    public void setOuch2IsSet(boolean value) {
      if (!value) {
        this.ouch2 = null;
      }
    }

    public TableNotFoundException getOuch3() {
      return this.ouch3;
    }

    public removeTableProperty_result setOuch3(TableNotFoundException ouch3) {
      this.ouch3 = ouch3;
      return this;
    }

    public void unsetOuch3() {
      this.ouch3 = null;
    }

    /** Returns true if field ouch3 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch3() {
      return this.ouch3 != null;
    }

    public void setOuch3IsSet(boolean value) {
      if (!value) {
        this.ouch3 = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case OUCH1:
        if (value == null) {
          unsetOuch1();
        } else {
          setOuch1((AccumuloException)value);
        }
        break;

      case OUCH2:
        if (value == null) {
          unsetOuch2();
        } else {
          setOuch2((AccumuloSecurityException)value);
        }
        break;

      case OUCH3:
        if (value == null) {
          unsetOuch3();
        } else {
          setOuch3((TableNotFoundException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case OUCH1:
        return getOuch1();

      case OUCH2:
        return getOuch2();

      case OUCH3:
        return getOuch3();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case OUCH1:
        return isSetOuch1();
      case OUCH2:
        return isSetOuch2();
      case OUCH3:
        return isSetOuch3();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof removeTableProperty_result)
        return this.equals((removeTableProperty_result)that);
      return false;
    }

    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();
      if (this_present_ouch1 || that_present_ouch1) {
        if (!(this_present_ouch1 && that_present_ouch1))
          return false;
        if (!this.ouch1.equals(that.ouch1))
          return false;
      }

      boolean this_present_ouch2 = true && this.isSetOuch2();
      boolean that_present_ouch2 = true && that.isSetOuch2();
      if (this_present_ouch2 || that_present_ouch2) {
        if (!(this_present_ouch2 && that_present_ouch2))
          return false;
        if (!this.ouch2.equals(that.ouch2))
          return false;
      }

      boolean this_present_ouch3 = true && this.isSetOuch3();
      boolean that_present_ouch3 = true && that.isSetOuch3();
      if (this_present_ouch3 || that_present_ouch3) {
        if (!(this_present_ouch3 && that_present_ouch3))
          return false;
        if (!this.ouch3.equals(that.ouch3))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
      if (isSetOuch1())
        hashCode = hashCode * 8191 + ouch1.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
      if (isSetOuch2())
        hashCode = hashCode * 8191 + ouch2.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
      if (isSetOuch3())
        hashCode = hashCode * 8191 + ouch3.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(removeTableProperty_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch1()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch2()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch3()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch3, other.ouch3);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("removeTableProperty_result(");
      boolean first = true;

      sb.append("ouch1:");
      if (this.ouch1 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch1);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch2:");
      if (this.ouch2 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch2);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch3:");
      if (this.ouch3 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch3);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class removeTableProperty_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public removeTableProperty_resultStandardScheme getScheme() {
        return new removeTableProperty_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // OUCH1
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch1 = new AccumuloException();
                struct.ouch1.read(iprot);
                struct.setOuch1IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OUCH2
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch2 = new AccumuloSecurityException();
                struct.ouch2.read(iprot);
                struct.setOuch2IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // OUCH3
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch3 = new TableNotFoundException();
                struct.ouch3.read(iprot);
                struct.setOuch3IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, removeTableProperty_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.ouch1 != null) {
          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
          struct.ouch1.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch2 != null) {
          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
          struct.ouch2.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch3 != null) {
          oprot.writeFieldBegin(OUCH3_FIELD_DESC);
          struct.ouch3.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class removeTableProperty_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public removeTableProperty_resultTupleScheme getScheme() {
        return new removeTableProperty_resultTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetOuch2()) {
          optionals.set(1);
        }
        if (struct.isSetOuch3()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetOuch1()) {
          struct.ouch1.write(oprot);
        }
        if (struct.isSetOuch2()) {
          struct.ouch2.write(oprot);
        }
        if (struct.isSetOuch3()) {
          struct.ouch3.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, removeTableProperty_result struct) throws org.apache.thrift.TException {
        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);
          struct.setOuch1IsSet(true);
        }
        if (incoming.get(1)) {
          struct.ouch2 = new AccumuloSecurityException();
          struct.ouch2.read(iprot);
          struct.setOuch2IsSet(true);
        }
        if (incoming.get(2)) {
          struct.ouch3 = new TableNotFoundException();
          struct.ouch3.read(iprot);
          struct.setOuch3IsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("renameTable_args");

    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField OLD_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 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 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 {
      LOGIN((short)1, "login"),
      OLD_TABLE_NAME((short)2, "oldTableName"),
      NEW_TABLE_NAME((short)3, "newTableName");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // LOGIN
            return LOGIN;
          case 2: // OLD_TABLE_NAME
            return OLD_TABLE_NAME;
          case 3: // NEW_TABLE_NAME
            return NEW_TABLE_NAME;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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 = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(renameTable_args.class, metaDataMap);
    }

    public renameTable_args() {
    }

    public renameTable_args(
      java.nio.ByteBuffer login,
      java.lang.String oldTableName,
      java.lang.String newTableName)
    {
      this();
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      this.oldTableName = oldTableName;
      this.newTableName = newTableName;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public renameTable_args(renameTable_args other) {
      if (other.isSetLogin()) {
        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
      }
      if (other.isSetOldTableName()) {
        this.oldTableName = other.oldTableName;
      }
      if (other.isSetNewTableName()) {
        this.newTableName = other.newTableName;
      }
    }

    public renameTable_args deepCopy() {
      return new renameTable_args(this);
    }

    @Override
    public void clear() {
      this.login = null;
      this.oldTableName = null;
      this.newTableName = null;
    }

    public byte[] getLogin() {
      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
      return login == null ? null : login.array();
    }

    public java.nio.ByteBuffer bufferForLogin() {
      return org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    public renameTable_args setLogin(byte[] login) {
      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
      return this;
    }

    public renameTable_args setLogin(java.nio.ByteBuffer login) {
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      return this;
    }

    public void unsetLogin() {
      this.login = null;
    }

    /** Returns true if field login is set (has been assigned a value) and false otherwise */
    public boolean isSetLogin() {
      return this.login != null;
    }

    public void setLoginIsSet(boolean value) {
      if (!value) {
        this.login = null;
      }
    }

    public java.lang.String getOldTableName() {
      return this.oldTableName;
    }

    public renameTable_args setOldTableName(java.lang.String oldTableName) {
      this.oldTableName = oldTableName;
      return this;
    }

    public void unsetOldTableName() {
      this.oldTableName = null;
    }

    /** Returns true if field oldTableName is set (has been assigned a value) and false otherwise */
    public boolean isSetOldTableName() {
      return this.oldTableName != null;
    }

    public void setOldTableNameIsSet(boolean value) {
      if (!value) {
        this.oldTableName = null;
      }
    }

    public java.lang.String getNewTableName() {
      return this.newTableName;
    }

    public renameTable_args setNewTableName(java.lang.String newTableName) {
      this.newTableName = newTableName;
      return this;
    }

    public void unsetNewTableName() {
      this.newTableName = null;
    }

    /** Returns true if field newTableName is set (has been assigned a value) and false otherwise */
    public boolean isSetNewTableName() {
      return this.newTableName != null;
    }

    public void setNewTableNameIsSet(boolean value) {
      if (!value) {
        this.newTableName = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case LOGIN:
        if (value == null) {
          unsetLogin();
        } else {
          if (value instanceof byte[]) {
            setLogin((byte[])value);
          } else {
            setLogin((java.nio.ByteBuffer)value);
          }
        }
        break;

      case OLD_TABLE_NAME:
        if (value == null) {
          unsetOldTableName();
        } else {
          setOldTableName((java.lang.String)value);
        }
        break;

      case NEW_TABLE_NAME:
        if (value == null) {
          unsetNewTableName();
        } else {
          setNewTableName((java.lang.String)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case LOGIN:
        return getLogin();

      case OLD_TABLE_NAME:
        return getOldTableName();

      case NEW_TABLE_NAME:
        return getNewTableName();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case LOGIN:
        return isSetLogin();
      case OLD_TABLE_NAME:
        return isSetOldTableName();
      case NEW_TABLE_NAME:
        return isSetNewTableName();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof renameTable_args)
        return this.equals((renameTable_args)that);
      return false;
    }

    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();
      if (this_present_login || that_present_login) {
        if (!(this_present_login && that_present_login))
          return false;
        if (!this.login.equals(that.login))
          return false;
      }

      boolean this_present_oldTableName = true && this.isSetOldTableName();
      boolean that_present_oldTableName = true && that.isSetOldTableName();
      if (this_present_oldTableName || that_present_oldTableName) {
        if (!(this_present_oldTableName && that_present_oldTableName))
          return false;
        if (!this.oldTableName.equals(that.oldTableName))
          return false;
      }

      boolean this_present_newTableName = true && this.isSetNewTableName();
      boolean that_present_newTableName = true && that.isSetNewTableName();
      if (this_present_newTableName || that_present_newTableName) {
        if (!(this_present_newTableName && that_present_newTableName))
          return false;
        if (!this.newTableName.equals(that.newTableName))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
      if (isSetLogin())
        hashCode = hashCode * 8191 + login.hashCode();

      hashCode = hashCode * 8191 + ((isSetOldTableName()) ? 131071 : 524287);
      if (isSetOldTableName())
        hashCode = hashCode * 8191 + oldTableName.hashCode();

      hashCode = hashCode * 8191 + ((isSetNewTableName()) ? 131071 : 524287);
      if (isSetNewTableName())
        hashCode = hashCode * 8191 + newTableName.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(renameTable_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLogin()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOldTableName()).compareTo(other.isSetOldTableName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOldTableName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.oldTableName, other.oldTableName);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetNewTableName()).compareTo(other.isSetNewTableName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetNewTableName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.newTableName, other.newTableName);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("renameTable_args(");
      boolean first = true;

      sb.append("login:");
      if (this.login == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.login, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("oldTableName:");
      if (this.oldTableName == null) {
        sb.append("null");
      } else {
        sb.append(this.oldTableName);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("newTableName:");
      if (this.newTableName == null) {
        sb.append("null");
      } else {
        sb.append(this.newTableName);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class renameTable_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public renameTable_argsStandardScheme getScheme() {
        return new renameTable_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // LOGIN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.login = iprot.readBinary();
                struct.setLoginIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OLD_TABLE_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.oldTableName = iprot.readString();
                struct.setOldTableNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // NEW_TABLE_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.newTableName = iprot.readString();
                struct.setNewTableNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, renameTable_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.login != null) {
          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
          oprot.writeBinary(struct.login);
          oprot.writeFieldEnd();
        }
        if (struct.oldTableName != null) {
          oprot.writeFieldBegin(OLD_TABLE_NAME_FIELD_DESC);
          oprot.writeString(struct.oldTableName);
          oprot.writeFieldEnd();
        }
        if (struct.newTableName != null) {
          oprot.writeFieldBegin(NEW_TABLE_NAME_FIELD_DESC);
          oprot.writeString(struct.newTableName);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    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 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 {
        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);
        }
        if (struct.isSetOldTableName()) {
          optionals.set(1);
        }
        if (struct.isSetNewTableName()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetLogin()) {
          oprot.writeBinary(struct.login);
        }
        if (struct.isSetOldTableName()) {
          oprot.writeString(struct.oldTableName);
        }
        if (struct.isSetNewTableName()) {
          oprot.writeString(struct.newTableName);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, renameTable_args struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.oldTableName = iprot.readString();
          struct.setOldTableNameIsSet(true);
        }
        if (incoming.get(2)) {
          struct.newTableName = iprot.readString();
          struct.setNewTableNameIsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("renameTable_result");

    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField OUCH3_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch3", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    private static final org.apache.thrift.protocol.TField OUCH4_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch4", org.apache.thrift.protocol.TType.STRUCT, (short)4);

    private static final 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
    public TableNotFoundException ouch3; // required
    public TableExistsException ouch4; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      OUCH1((short)1, "ouch1"),
      OUCH2((short)2, "ouch2"),
      OUCH3((short)3, "ouch3"),
      OUCH4((short)4, "ouch4");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // OUCH1
            return OUCH1;
          case 2: // OUCH2
            return OUCH2;
          case 3: // OUCH3
            return OUCH3;
          case 4: // OUCH4
            return OUCH4;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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.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.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.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);
    }

    public renameTable_result() {
    }

    public renameTable_result(
      AccumuloException ouch1,
      AccumuloSecurityException ouch2,
      TableNotFoundException ouch3,
      TableExistsException ouch4)
    {
      this();
      this.ouch1 = ouch1;
      this.ouch2 = ouch2;
      this.ouch3 = ouch3;
      this.ouch4 = ouch4;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public renameTable_result(renameTable_result other) {
      if (other.isSetOuch1()) {
        this.ouch1 = new AccumuloException(other.ouch1);
      }
      if (other.isSetOuch2()) {
        this.ouch2 = new AccumuloSecurityException(other.ouch2);
      }
      if (other.isSetOuch3()) {
        this.ouch3 = new TableNotFoundException(other.ouch3);
      }
      if (other.isSetOuch4()) {
        this.ouch4 = new TableExistsException(other.ouch4);
      }
    }

    public renameTable_result deepCopy() {
      return new renameTable_result(this);
    }

    @Override
    public void clear() {
      this.ouch1 = null;
      this.ouch2 = null;
      this.ouch3 = null;
      this.ouch4 = null;
    }

    public AccumuloException getOuch1() {
      return this.ouch1;
    }

    public renameTable_result setOuch1(AccumuloException ouch1) {
      this.ouch1 = ouch1;
      return this;
    }

    public void unsetOuch1() {
      this.ouch1 = null;
    }

    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch1() {
      return this.ouch1 != null;
    }

    public void setOuch1IsSet(boolean value) {
      if (!value) {
        this.ouch1 = null;
      }
    }

    public AccumuloSecurityException getOuch2() {
      return this.ouch2;
    }

    public renameTable_result setOuch2(AccumuloSecurityException ouch2) {
      this.ouch2 = ouch2;
      return this;
    }

    public void unsetOuch2() {
      this.ouch2 = null;
    }

    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch2() {
      return this.ouch2 != null;
    }

    public void setOuch2IsSet(boolean value) {
      if (!value) {
        this.ouch2 = null;
      }
    }

    public TableNotFoundException getOuch3() {
      return this.ouch3;
    }

    public renameTable_result setOuch3(TableNotFoundException ouch3) {
      this.ouch3 = ouch3;
      return this;
    }

    public void unsetOuch3() {
      this.ouch3 = null;
    }

    /** Returns true if field ouch3 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch3() {
      return this.ouch3 != null;
    }

    public void setOuch3IsSet(boolean value) {
      if (!value) {
        this.ouch3 = null;
      }
    }

    public TableExistsException getOuch4() {
      return this.ouch4;
    }

    public renameTable_result setOuch4(TableExistsException ouch4) {
      this.ouch4 = ouch4;
      return this;
    }

    public void unsetOuch4() {
      this.ouch4 = null;
    }

    /** Returns true if field ouch4 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch4() {
      return this.ouch4 != null;
    }

    public void setOuch4IsSet(boolean value) {
      if (!value) {
        this.ouch4 = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case OUCH1:
        if (value == null) {
          unsetOuch1();
        } else {
          setOuch1((AccumuloException)value);
        }
        break;

      case OUCH2:
        if (value == null) {
          unsetOuch2();
        } else {
          setOuch2((AccumuloSecurityException)value);
        }
        break;

      case OUCH3:
        if (value == null) {
          unsetOuch3();
        } else {
          setOuch3((TableNotFoundException)value);
        }
        break;

      case OUCH4:
        if (value == null) {
          unsetOuch4();
        } else {
          setOuch4((TableExistsException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case OUCH1:
        return getOuch1();

      case OUCH2:
        return getOuch2();

      case OUCH3:
        return getOuch3();

      case OUCH4:
        return getOuch4();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case OUCH1:
        return isSetOuch1();
      case OUCH2:
        return isSetOuch2();
      case OUCH3:
        return isSetOuch3();
      case OUCH4:
        return isSetOuch4();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof renameTable_result)
        return this.equals((renameTable_result)that);
      return false;
    }

    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();
      if (this_present_ouch1 || that_present_ouch1) {
        if (!(this_present_ouch1 && that_present_ouch1))
          return false;
        if (!this.ouch1.equals(that.ouch1))
          return false;
      }

      boolean this_present_ouch2 = true && this.isSetOuch2();
      boolean that_present_ouch2 = true && that.isSetOuch2();
      if (this_present_ouch2 || that_present_ouch2) {
        if (!(this_present_ouch2 && that_present_ouch2))
          return false;
        if (!this.ouch2.equals(that.ouch2))
          return false;
      }

      boolean this_present_ouch3 = true && this.isSetOuch3();
      boolean that_present_ouch3 = true && that.isSetOuch3();
      if (this_present_ouch3 || that_present_ouch3) {
        if (!(this_present_ouch3 && that_present_ouch3))
          return false;
        if (!this.ouch3.equals(that.ouch3))
          return false;
      }

      boolean this_present_ouch4 = true && this.isSetOuch4();
      boolean that_present_ouch4 = true && that.isSetOuch4();
      if (this_present_ouch4 || that_present_ouch4) {
        if (!(this_present_ouch4 && that_present_ouch4))
          return false;
        if (!this.ouch4.equals(that.ouch4))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
      if (isSetOuch1())
        hashCode = hashCode * 8191 + ouch1.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
      if (isSetOuch2())
        hashCode = hashCode * 8191 + ouch2.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
      if (isSetOuch3())
        hashCode = hashCode * 8191 + ouch3.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch4()) ? 131071 : 524287);
      if (isSetOuch4())
        hashCode = hashCode * 8191 + ouch4.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(renameTable_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch1()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch2()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch3()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch3, other.ouch3);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch4()).compareTo(other.isSetOuch4());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch4()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch4, other.ouch4);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("renameTable_result(");
      boolean first = true;

      sb.append("ouch1:");
      if (this.ouch1 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch1);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch2:");
      if (this.ouch2 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch2);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch3:");
      if (this.ouch3 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch3);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch4:");
      if (this.ouch4 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch4);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class renameTable_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public renameTable_resultStandardScheme getScheme() {
        return new renameTable_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // OUCH1
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch1 = new AccumuloException();
                struct.ouch1.read(iprot);
                struct.setOuch1IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OUCH2
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch2 = new AccumuloSecurityException();
                struct.ouch2.read(iprot);
                struct.setOuch2IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // OUCH3
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch3 = new TableNotFoundException();
                struct.ouch3.read(iprot);
                struct.setOuch3IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // OUCH4
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch4 = new TableExistsException();
                struct.ouch4.read(iprot);
                struct.setOuch4IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, renameTable_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.ouch1 != null) {
          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
          struct.ouch1.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch2 != null) {
          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
          struct.ouch2.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch3 != null) {
          oprot.writeFieldBegin(OUCH3_FIELD_DESC);
          struct.ouch3.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch4 != null) {
          oprot.writeFieldBegin(OUCH4_FIELD_DESC);
          struct.ouch4.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class renameTable_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public renameTable_resultTupleScheme getScheme() {
        return new renameTable_resultTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetOuch2()) {
          optionals.set(1);
        }
        if (struct.isSetOuch3()) {
          optionals.set(2);
        }
        if (struct.isSetOuch4()) {
          optionals.set(3);
        }
        oprot.writeBitSet(optionals, 4);
        if (struct.isSetOuch1()) {
          struct.ouch1.write(oprot);
        }
        if (struct.isSetOuch2()) {
          struct.ouch2.write(oprot);
        }
        if (struct.isSetOuch3()) {
          struct.ouch3.write(oprot);
        }
        if (struct.isSetOuch4()) {
          struct.ouch4.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, renameTable_result struct) throws org.apache.thrift.TException {
        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);
          struct.setOuch1IsSet(true);
        }
        if (incoming.get(1)) {
          struct.ouch2 = new AccumuloSecurityException();
          struct.ouch2.read(iprot);
          struct.setOuch2IsSet(true);
        }
        if (incoming.get(2)) {
          struct.ouch3 = new TableNotFoundException();
          struct.ouch3.read(iprot);
          struct.setOuch3IsSet(true);
        }
        if (incoming.get(3)) {
          struct.ouch4 = new TableExistsException();
          struct.ouch4.read(iprot);
          struct.setOuch4IsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("setLocalityGroups_args");

    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField 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 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 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 {
      LOGIN((short)1, "login"),
      TABLE_NAME((short)2, "tableName"),
      GROUPS((short)3, "groups");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // LOGIN
            return LOGIN;
          case 2: // TABLE_NAME
            return TABLE_NAME;
          case 3: // GROUPS
            return GROUPS;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.GROUPS, new org.apache.thrift.meta_data.FieldMetaData("groups", 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)))));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(setLocalityGroups_args.class, metaDataMap);
    }

    public setLocalityGroups_args() {
    }

    public setLocalityGroups_args(
      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);
      this.tableName = tableName;
      this.groups = groups;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public setLocalityGroups_args(setLocalityGroups_args other) {
      if (other.isSetLogin()) {
        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
      }
      if (other.isSetTableName()) {
        this.tableName = other.tableName;
      }
      if (other.isSetGroups()) {
        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()) {

          java.lang.String other_element_key = other_element.getKey();
          java.util.Set<java.lang.String> other_element_value = other_element.getValue();

          java.lang.String __this__groups_copy_key = other_element_key;

          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);
        }
        this.groups = __this__groups;
      }
    }

    public setLocalityGroups_args deepCopy() {
      return new setLocalityGroups_args(this);
    }

    @Override
    public void clear() {
      this.login = null;
      this.tableName = null;
      this.groups = null;
    }

    public byte[] getLogin() {
      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
      return login == null ? null : login.array();
    }

    public java.nio.ByteBuffer bufferForLogin() {
      return org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    public setLocalityGroups_args setLogin(byte[] login) {
      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
      return this;
    }

    public setLocalityGroups_args setLogin(java.nio.ByteBuffer login) {
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      return this;
    }

    public void unsetLogin() {
      this.login = null;
    }

    /** Returns true if field login is set (has been assigned a value) and false otherwise */
    public boolean isSetLogin() {
      return this.login != null;
    }

    public void setLoginIsSet(boolean value) {
      if (!value) {
        this.login = null;
      }
    }

    public java.lang.String getTableName() {
      return this.tableName;
    }

    public setLocalityGroups_args setTableName(java.lang.String tableName) {
      this.tableName = tableName;
      return this;
    }

    public void unsetTableName() {
      this.tableName = null;
    }

    /** Returns true if field tableName is set (has been assigned a value) and false otherwise */
    public boolean isSetTableName() {
      return this.tableName != null;
    }

    public void setTableNameIsSet(boolean value) {
      if (!value) {
        this.tableName = null;
      }
    }

    public int getGroupsSize() {
      return (this.groups == null) ? 0 : this.groups.size();
    }

    public void putToGroups(java.lang.String key, java.util.Set<java.lang.String> val) {
      if (this.groups == null) {
        this.groups = new java.util.HashMap<java.lang.String,java.util.Set<java.lang.String>>();
      }
      this.groups.put(key, val);
    }

    public java.util.Map<java.lang.String,java.util.Set<java.lang.String>> getGroups() {
      return this.groups;
    }

    public setLocalityGroups_args setGroups(java.util.Map<java.lang.String,java.util.Set<java.lang.String>> groups) {
      this.groups = groups;
      return this;
    }

    public void unsetGroups() {
      this.groups = null;
    }

    /** Returns true if field groups is set (has been assigned a value) and false otherwise */
    public boolean isSetGroups() {
      return this.groups != null;
    }

    public void setGroupsIsSet(boolean value) {
      if (!value) {
        this.groups = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case LOGIN:
        if (value == null) {
          unsetLogin();
        } else {
          if (value instanceof byte[]) {
            setLogin((byte[])value);
          } else {
            setLogin((java.nio.ByteBuffer)value);
          }
        }
        break;

      case TABLE_NAME:
        if (value == null) {
          unsetTableName();
        } else {
          setTableName((java.lang.String)value);
        }
        break;

      case GROUPS:
        if (value == null) {
          unsetGroups();
        } else {
          setGroups((java.util.Map<java.lang.String,java.util.Set<java.lang.String>>)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case LOGIN:
        return getLogin();

      case TABLE_NAME:
        return getTableName();

      case GROUPS:
        return getGroups();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case LOGIN:
        return isSetLogin();
      case TABLE_NAME:
        return isSetTableName();
      case GROUPS:
        return isSetGroups();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof setLocalityGroups_args)
        return this.equals((setLocalityGroups_args)that);
      return false;
    }

    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();
      if (this_present_login || that_present_login) {
        if (!(this_present_login && that_present_login))
          return false;
        if (!this.login.equals(that.login))
          return false;
      }

      boolean this_present_tableName = true && this.isSetTableName();
      boolean that_present_tableName = true && that.isSetTableName();
      if (this_present_tableName || that_present_tableName) {
        if (!(this_present_tableName && that_present_tableName))
          return false;
        if (!this.tableName.equals(that.tableName))
          return false;
      }

      boolean this_present_groups = true && this.isSetGroups();
      boolean that_present_groups = true && that.isSetGroups();
      if (this_present_groups || that_present_groups) {
        if (!(this_present_groups && that_present_groups))
          return false;
        if (!this.groups.equals(that.groups))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
      if (isSetLogin())
        hashCode = hashCode * 8191 + login.hashCode();

      hashCode = hashCode * 8191 + ((isSetTableName()) ? 131071 : 524287);
      if (isSetTableName())
        hashCode = hashCode * 8191 + tableName.hashCode();

      hashCode = hashCode * 8191 + ((isSetGroups()) ? 131071 : 524287);
      if (isSetGroups())
        hashCode = hashCode * 8191 + groups.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(setLocalityGroups_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLogin()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetTableName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.tableName, other.tableName);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetGroups()).compareTo(other.isSetGroups());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetGroups()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.groups, other.groups);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("setLocalityGroups_args(");
      boolean first = true;

      sb.append("login:");
      if (this.login == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.login, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("tableName:");
      if (this.tableName == null) {
        sb.append("null");
      } else {
        sb.append(this.tableName);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("groups:");
      if (this.groups == null) {
        sb.append("null");
      } else {
        sb.append(this.groups);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class setLocalityGroups_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public setLocalityGroups_argsStandardScheme getScheme() {
        return new setLocalityGroups_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // LOGIN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.login = iprot.readBinary();
                struct.setLoginIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // TABLE_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.tableName = iprot.readString();
                struct.setTableNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // GROUPS
              if (schemeField.type == org.apache.thrift.protocol.TType.MAP) {
                {
                  org.apache.thrift.protocol.TMap _map328 = iprot.readMapBegin();
                  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 java.util.HashSet<java.lang.String>(2*_set332.size);
                      java.lang.String _elem333;
                      for (int _i334 = 0; _i334 < _set332.size; ++_i334)
                      {
                        _elem333 = iprot.readString();
                        _val330.add(_elem333);
                      }
                      iprot.readSetEnd();
                    }
                    struct.groups.put(_key329, _val330);
                  }
                  iprot.readMapEnd();
                }
                struct.setGroupsIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, setLocalityGroups_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.login != null) {
          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
          oprot.writeBinary(struct.login);
          oprot.writeFieldEnd();
        }
        if (struct.tableName != null) {
          oprot.writeFieldBegin(TABLE_NAME_FIELD_DESC);
          oprot.writeString(struct.tableName);
          oprot.writeFieldEnd();
        }
        if (struct.groups != null) {
          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 (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 (java.lang.String _iter336 : _iter335.getValue())
                {
                  oprot.writeString(_iter336);
                }
                oprot.writeSetEnd();
              }
            }
            oprot.writeMapEnd();
          }
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    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 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 {
        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);
        }
        if (struct.isSetTableName()) {
          optionals.set(1);
        }
        if (struct.isSetGroups()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetLogin()) {
          oprot.writeBinary(struct.login);
        }
        if (struct.isSetTableName()) {
          oprot.writeString(struct.tableName);
        }
        if (struct.isSetGroups()) {
          {
            oprot.writeI32(struct.groups.size());
            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 (java.lang.String _iter338 : _iter337.getValue())
                {
                  oprot.writeString(_iter338);
                }
              }
            }
          }
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, setLocalityGroups_args struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.tableName = iprot.readString();
          struct.setTableNameIsSet(true);
        }
        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 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 java.util.HashSet<java.lang.String>(2*_set343.size);
                java.lang.String _elem344;
                for (int _i345 = 0; _i345 < _set343.size; ++_i345)
                {
                  _elem344 = iprot.readString();
                  _val341.add(_elem344);
                }
              }
              struct.groups.put(_key340, _val341);
            }
          }
          struct.setGroupsIsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("setLocalityGroups_result");

    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField OUCH3_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch3", org.apache.thrift.protocol.TType.STRUCT, (short)3);

    private static final org.apache.thrift.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
    public TableNotFoundException ouch3; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      OUCH1((short)1, "ouch1"),
      OUCH2((short)2, "ouch2"),
      OUCH3((short)3, "ouch3");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // OUCH1
            return OUCH1;
          case 2: // OUCH2
            return OUCH2;
          case 3: // OUCH3
            return OUCH3;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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.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.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);
    }

    public setLocalityGroups_result() {
    }

    public setLocalityGroups_result(
      AccumuloException ouch1,
      AccumuloSecurityException ouch2,
      TableNotFoundException ouch3)
    {
      this();
      this.ouch1 = ouch1;
      this.ouch2 = ouch2;
      this.ouch3 = ouch3;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public setLocalityGroups_result(setLocalityGroups_result other) {
      if (other.isSetOuch1()) {
        this.ouch1 = new AccumuloException(other.ouch1);
      }
      if (other.isSetOuch2()) {
        this.ouch2 = new AccumuloSecurityException(other.ouch2);
      }
      if (other.isSetOuch3()) {
        this.ouch3 = new TableNotFoundException(other.ouch3);
      }
    }

    public setLocalityGroups_result deepCopy() {
      return new setLocalityGroups_result(this);
    }

    @Override
    public void clear() {
      this.ouch1 = null;
      this.ouch2 = null;
      this.ouch3 = null;
    }

    public AccumuloException getOuch1() {
      return this.ouch1;
    }

    public setLocalityGroups_result setOuch1(AccumuloException ouch1) {
      this.ouch1 = ouch1;
      return this;
    }

    public void unsetOuch1() {
      this.ouch1 = null;
    }

    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch1() {
      return this.ouch1 != null;
    }

    public void setOuch1IsSet(boolean value) {
      if (!value) {
        this.ouch1 = null;
      }
    }

    public AccumuloSecurityException getOuch2() {
      return this.ouch2;
    }

    public setLocalityGroups_result setOuch2(AccumuloSecurityException ouch2) {
      this.ouch2 = ouch2;
      return this;
    }

    public void unsetOuch2() {
      this.ouch2 = null;
    }

    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch2() {
      return this.ouch2 != null;
    }

    public void setOuch2IsSet(boolean value) {
      if (!value) {
        this.ouch2 = null;
      }
    }

    public TableNotFoundException getOuch3() {
      return this.ouch3;
    }

    public setLocalityGroups_result setOuch3(TableNotFoundException ouch3) {
      this.ouch3 = ouch3;
      return this;
    }

    public void unsetOuch3() {
      this.ouch3 = null;
    }

    /** Returns true if field ouch3 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch3() {
      return this.ouch3 != null;
    }

    public void setOuch3IsSet(boolean value) {
      if (!value) {
        this.ouch3 = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case OUCH1:
        if (value == null) {
          unsetOuch1();
        } else {
          setOuch1((AccumuloException)value);
        }
        break;

      case OUCH2:
        if (value == null) {
          unsetOuch2();
        } else {
          setOuch2((AccumuloSecurityException)value);
        }
        break;

      case OUCH3:
        if (value == null) {
          unsetOuch3();
        } else {
          setOuch3((TableNotFoundException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case OUCH1:
        return getOuch1();

      case OUCH2:
        return getOuch2();

      case OUCH3:
        return getOuch3();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case OUCH1:
        return isSetOuch1();
      case OUCH2:
        return isSetOuch2();
      case OUCH3:
        return isSetOuch3();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof setLocalityGroups_result)
        return this.equals((setLocalityGroups_result)that);
      return false;
    }

    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();
      if (this_present_ouch1 || that_present_ouch1) {
        if (!(this_present_ouch1 && that_present_ouch1))
          return false;
        if (!this.ouch1.equals(that.ouch1))
          return false;
      }

      boolean this_present_ouch2 = true && this.isSetOuch2();
      boolean that_present_ouch2 = true && that.isSetOuch2();
      if (this_present_ouch2 || that_present_ouch2) {
        if (!(this_present_ouch2 && that_present_ouch2))
          return false;
        if (!this.ouch2.equals(that.ouch2))
          return false;
      }

      boolean this_present_ouch3 = true && this.isSetOuch3();
      boolean that_present_ouch3 = true && that.isSetOuch3();
      if (this_present_ouch3 || that_present_ouch3) {
        if (!(this_present_ouch3 && that_present_ouch3))
          return false;
        if (!this.ouch3.equals(that.ouch3))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
      if (isSetOuch1())
        hashCode = hashCode * 8191 + ouch1.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
      if (isSetOuch2())
        hashCode = hashCode * 8191 + ouch2.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
      if (isSetOuch3())
        hashCode = hashCode * 8191 + ouch3.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(setLocalityGroups_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch1()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch2()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch3()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch3, other.ouch3);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("setLocalityGroups_result(");
      boolean first = true;

      sb.append("ouch1:");
      if (this.ouch1 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch1);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch2:");
      if (this.ouch2 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch2);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch3:");
      if (this.ouch3 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch3);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class setLocalityGroups_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public setLocalityGroups_resultStandardScheme getScheme() {
        return new setLocalityGroups_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // OUCH1
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch1 = new AccumuloException();
                struct.ouch1.read(iprot);
                struct.setOuch1IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OUCH2
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch2 = new AccumuloSecurityException();
                struct.ouch2.read(iprot);
                struct.setOuch2IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // OUCH3
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch3 = new TableNotFoundException();
                struct.ouch3.read(iprot);
                struct.setOuch3IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, setLocalityGroups_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.ouch1 != null) {
          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
          struct.ouch1.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch2 != null) {
          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
          struct.ouch2.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch3 != null) {
          oprot.writeFieldBegin(OUCH3_FIELD_DESC);
          struct.ouch3.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class setLocalityGroups_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public setLocalityGroups_resultTupleScheme getScheme() {
        return new setLocalityGroups_resultTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetOuch2()) {
          optionals.set(1);
        }
        if (struct.isSetOuch3()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetOuch1()) {
          struct.ouch1.write(oprot);
        }
        if (struct.isSetOuch2()) {
          struct.ouch2.write(oprot);
        }
        if (struct.isSetOuch3()) {
          struct.ouch3.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, setLocalityGroups_result struct) throws org.apache.thrift.TException {
        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);
          struct.setOuch1IsSet(true);
        }
        if (incoming.get(1)) {
          struct.ouch2 = new AccumuloSecurityException();
          struct.ouch2.read(iprot);
          struct.setOuch2IsSet(true);
        }
        if (incoming.get(2)) {
          struct.ouch3 = new TableNotFoundException();
          struct.ouch3.read(iprot);
          struct.setOuch3IsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("setTableProperty_args");

    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField 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 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 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 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 {
      LOGIN((short)1, "login"),
      TABLE_NAME((short)2, "tableName"),
      PROPERTY((short)3, "property"),
      VALUE((short)4, "value");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // LOGIN
            return LOGIN;
          case 2: // TABLE_NAME
            return TABLE_NAME;
          case 3: // PROPERTY
            return PROPERTY;
          case 4: // VALUE
            return VALUE;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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)));
      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 = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(setTableProperty_args.class, metaDataMap);
    }

    public setTableProperty_args() {
    }

    public setTableProperty_args(
      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);
      this.tableName = tableName;
      this.property = property;
      this.value = value;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public setTableProperty_args(setTableProperty_args other) {
      if (other.isSetLogin()) {
        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
      }
      if (other.isSetTableName()) {
        this.tableName = other.tableName;
      }
      if (other.isSetProperty()) {
        this.property = other.property;
      }
      if (other.isSetValue()) {
        this.value = other.value;
      }
    }

    public setTableProperty_args deepCopy() {
      return new setTableProperty_args(this);
    }

    @Override
    public void clear() {
      this.login = null;
      this.tableName = null;
      this.property = null;
      this.value = null;
    }

    public byte[] getLogin() {
      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
      return login == null ? null : login.array();
    }

    public java.nio.ByteBuffer bufferForLogin() {
      return org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    public setTableProperty_args setLogin(byte[] login) {
      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
      return this;
    }

    public setTableProperty_args setLogin(java.nio.ByteBuffer login) {
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      return this;
    }

    public void unsetLogin() {
      this.login = null;
    }

    /** Returns true if field login is set (has been assigned a value) and false otherwise */
    public boolean isSetLogin() {
      return this.login != null;
    }

    public void setLoginIsSet(boolean value) {
      if (!value) {
        this.login = null;
      }
    }

    public java.lang.String getTableName() {
      return this.tableName;
    }

    public setTableProperty_args setTableName(java.lang.String tableName) {
      this.tableName = tableName;
      return this;
    }

    public void unsetTableName() {
      this.tableName = null;
    }

    /** Returns true if field tableName is set (has been assigned a value) and false otherwise */
    public boolean isSetTableName() {
      return this.tableName != null;
    }

    public void setTableNameIsSet(boolean value) {
      if (!value) {
        this.tableName = null;
      }
    }

    public java.lang.String getProperty() {
      return this.property;
    }

    public setTableProperty_args setProperty(java.lang.String property) {
      this.property = property;
      return this;
    }

    public void unsetProperty() {
      this.property = null;
    }

    /** Returns true if field property is set (has been assigned a value) and false otherwise */
    public boolean isSetProperty() {
      return this.property != null;
    }

    public void setPropertyIsSet(boolean value) {
      if (!value) {
        this.property = null;
      }
    }

    public java.lang.String getValue() {
      return this.value;
    }

    public setTableProperty_args setValue(java.lang.String value) {
      this.value = value;
      return this;
    }

    public void unsetValue() {
      this.value = null;
    }

    /** Returns true if field value is set (has been assigned a value) and false otherwise */
    public boolean isSetValue() {
      return this.value != null;
    }

    public void setValueIsSet(boolean value) {
      if (!value) {
        this.value = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case LOGIN:
        if (value == null) {
          unsetLogin();
        } else {
          if (value instanceof byte[]) {
            setLogin((byte[])value);
          } else {
            setLogin((java.nio.ByteBuffer)value);
          }
        }
        break;

      case TABLE_NAME:
        if (value == null) {
          unsetTableName();
        } else {
          setTableName((java.lang.String)value);
        }
        break;

      case PROPERTY:
        if (value == null) {
          unsetProperty();
        } else {
          setProperty((java.lang.String)value);
        }
        break;

      case VALUE:
        if (value == null) {
          unsetValue();
        } else {
          setValue((java.lang.String)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case LOGIN:
        return getLogin();

      case TABLE_NAME:
        return getTableName();

      case PROPERTY:
        return getProperty();

      case VALUE:
        return getValue();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case LOGIN:
        return isSetLogin();
      case TABLE_NAME:
        return isSetTableName();
      case PROPERTY:
        return isSetProperty();
      case VALUE:
        return isSetValue();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof setTableProperty_args)
        return this.equals((setTableProperty_args)that);
      return false;
    }

    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();
      if (this_present_login || that_present_login) {
        if (!(this_present_login && that_present_login))
          return false;
        if (!this.login.equals(that.login))
          return false;
      }

      boolean this_present_tableName = true && this.isSetTableName();
      boolean that_present_tableName = true && that.isSetTableName();
      if (this_present_tableName || that_present_tableName) {
        if (!(this_present_tableName && that_present_tableName))
          return false;
        if (!this.tableName.equals(that.tableName))
          return false;
      }

      boolean this_present_property = true && this.isSetProperty();
      boolean that_present_property = true && that.isSetProperty();
      if (this_present_property || that_present_property) {
        if (!(this_present_property && that_present_property))
          return false;
        if (!this.property.equals(that.property))
          return false;
      }

      boolean this_present_value = true && this.isSetValue();
      boolean that_present_value = true && that.isSetValue();
      if (this_present_value || that_present_value) {
        if (!(this_present_value && that_present_value))
          return false;
        if (!this.value.equals(that.value))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
      if (isSetLogin())
        hashCode = hashCode * 8191 + login.hashCode();

      hashCode = hashCode * 8191 + ((isSetTableName()) ? 131071 : 524287);
      if (isSetTableName())
        hashCode = hashCode * 8191 + tableName.hashCode();

      hashCode = hashCode * 8191 + ((isSetProperty()) ? 131071 : 524287);
      if (isSetProperty())
        hashCode = hashCode * 8191 + property.hashCode();

      hashCode = hashCode * 8191 + ((isSetValue()) ? 131071 : 524287);
      if (isSetValue())
        hashCode = hashCode * 8191 + value.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(setTableProperty_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLogin()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetTableName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.tableName, other.tableName);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetProperty()).compareTo(other.isSetProperty());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetProperty()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.property, other.property);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetValue()).compareTo(other.isSetValue());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetValue()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.value, other.value);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("setTableProperty_args(");
      boolean first = true;

      sb.append("login:");
      if (this.login == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.login, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("tableName:");
      if (this.tableName == null) {
        sb.append("null");
      } else {
        sb.append(this.tableName);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("property:");
      if (this.property == null) {
        sb.append("null");
      } else {
        sb.append(this.property);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("value:");
      if (this.value == null) {
        sb.append("null");
      } else {
        sb.append(this.value);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class setTableProperty_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public setTableProperty_argsStandardScheme getScheme() {
        return new setTableProperty_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // LOGIN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.login = iprot.readBinary();
                struct.setLoginIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // TABLE_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.tableName = iprot.readString();
                struct.setTableNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // PROPERTY
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.property = iprot.readString();
                struct.setPropertyIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // VALUE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.value = iprot.readString();
                struct.setValueIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, setTableProperty_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.login != null) {
          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
          oprot.writeBinary(struct.login);
          oprot.writeFieldEnd();
        }
        if (struct.tableName != null) {
          oprot.writeFieldBegin(TABLE_NAME_FIELD_DESC);
          oprot.writeString(struct.tableName);
          oprot.writeFieldEnd();
        }
        if (struct.property != null) {
          oprot.writeFieldBegin(PROPERTY_FIELD_DESC);
          oprot.writeString(struct.property);
          oprot.writeFieldEnd();
        }
        if (struct.value != null) {
          oprot.writeFieldBegin(VALUE_FIELD_DESC);
          oprot.writeString(struct.value);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class setTableProperty_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public setTableProperty_argsTupleScheme getScheme() {
        return new setTableProperty_argsTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetTableName()) {
          optionals.set(1);
        }
        if (struct.isSetProperty()) {
          optionals.set(2);
        }
        if (struct.isSetValue()) {
          optionals.set(3);
        }
        oprot.writeBitSet(optionals, 4);
        if (struct.isSetLogin()) {
          oprot.writeBinary(struct.login);
        }
        if (struct.isSetTableName()) {
          oprot.writeString(struct.tableName);
        }
        if (struct.isSetProperty()) {
          oprot.writeString(struct.property);
        }
        if (struct.isSetValue()) {
          oprot.writeString(struct.value);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, setTableProperty_args struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.tableName = iprot.readString();
          struct.setTableNameIsSet(true);
        }
        if (incoming.get(2)) {
          struct.property = iprot.readString();
          struct.setPropertyIsSet(true);
        }
        if (incoming.get(3)) {
          struct.value = iprot.readString();
          struct.setValueIsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("setTableProperty_result");

    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField OUCH3_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch3", org.apache.thrift.protocol.TType.STRUCT, (short)3);

    private static final org.apache.thrift.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
    public TableNotFoundException ouch3; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      OUCH1((short)1, "ouch1"),
      OUCH2((short)2, "ouch2"),
      OUCH3((short)3, "ouch3");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // OUCH1
            return OUCH1;
          case 2: // OUCH2
            return OUCH2;
          case 3: // OUCH3
            return OUCH3;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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.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.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);
    }

    public setTableProperty_result() {
    }

    public setTableProperty_result(
      AccumuloException ouch1,
      AccumuloSecurityException ouch2,
      TableNotFoundException ouch3)
    {
      this();
      this.ouch1 = ouch1;
      this.ouch2 = ouch2;
      this.ouch3 = ouch3;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public setTableProperty_result(setTableProperty_result other) {
      if (other.isSetOuch1()) {
        this.ouch1 = new AccumuloException(other.ouch1);
      }
      if (other.isSetOuch2()) {
        this.ouch2 = new AccumuloSecurityException(other.ouch2);
      }
      if (other.isSetOuch3()) {
        this.ouch3 = new TableNotFoundException(other.ouch3);
      }
    }

    public setTableProperty_result deepCopy() {
      return new setTableProperty_result(this);
    }

    @Override
    public void clear() {
      this.ouch1 = null;
      this.ouch2 = null;
      this.ouch3 = null;
    }

    public AccumuloException getOuch1() {
      return this.ouch1;
    }

    public setTableProperty_result setOuch1(AccumuloException ouch1) {
      this.ouch1 = ouch1;
      return this;
    }

    public void unsetOuch1() {
      this.ouch1 = null;
    }

    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch1() {
      return this.ouch1 != null;
    }

    public void setOuch1IsSet(boolean value) {
      if (!value) {
        this.ouch1 = null;
      }
    }

    public AccumuloSecurityException getOuch2() {
      return this.ouch2;
    }

    public setTableProperty_result setOuch2(AccumuloSecurityException ouch2) {
      this.ouch2 = ouch2;
      return this;
    }

    public void unsetOuch2() {
      this.ouch2 = null;
    }

    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch2() {
      return this.ouch2 != null;
    }

    public void setOuch2IsSet(boolean value) {
      if (!value) {
        this.ouch2 = null;
      }
    }

    public TableNotFoundException getOuch3() {
      return this.ouch3;
    }

    public setTableProperty_result setOuch3(TableNotFoundException ouch3) {
      this.ouch3 = ouch3;
      return this;
    }

    public void unsetOuch3() {
      this.ouch3 = null;
    }

    /** Returns true if field ouch3 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch3() {
      return this.ouch3 != null;
    }

    public void setOuch3IsSet(boolean value) {
      if (!value) {
        this.ouch3 = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case OUCH1:
        if (value == null) {
          unsetOuch1();
        } else {
          setOuch1((AccumuloException)value);
        }
        break;

      case OUCH2:
        if (value == null) {
          unsetOuch2();
        } else {
          setOuch2((AccumuloSecurityException)value);
        }
        break;

      case OUCH3:
        if (value == null) {
          unsetOuch3();
        } else {
          setOuch3((TableNotFoundException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case OUCH1:
        return getOuch1();

      case OUCH2:
        return getOuch2();

      case OUCH3:
        return getOuch3();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case OUCH1:
        return isSetOuch1();
      case OUCH2:
        return isSetOuch2();
      case OUCH3:
        return isSetOuch3();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof setTableProperty_result)
        return this.equals((setTableProperty_result)that);
      return false;
    }

    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();
      if (this_present_ouch1 || that_present_ouch1) {
        if (!(this_present_ouch1 && that_present_ouch1))
          return false;
        if (!this.ouch1.equals(that.ouch1))
          return false;
      }

      boolean this_present_ouch2 = true && this.isSetOuch2();
      boolean that_present_ouch2 = true && that.isSetOuch2();
      if (this_present_ouch2 || that_present_ouch2) {
        if (!(this_present_ouch2 && that_present_ouch2))
          return false;
        if (!this.ouch2.equals(that.ouch2))
          return false;
      }

      boolean this_present_ouch3 = true && this.isSetOuch3();
      boolean that_present_ouch3 = true && that.isSetOuch3();
      if (this_present_ouch3 || that_present_ouch3) {
        if (!(this_present_ouch3 && that_present_ouch3))
          return false;
        if (!this.ouch3.equals(that.ouch3))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
      if (isSetOuch1())
        hashCode = hashCode * 8191 + ouch1.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
      if (isSetOuch2())
        hashCode = hashCode * 8191 + ouch2.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
      if (isSetOuch3())
        hashCode = hashCode * 8191 + ouch3.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(setTableProperty_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch1()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch2()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch3()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch3, other.ouch3);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("setTableProperty_result(");
      boolean first = true;

      sb.append("ouch1:");
      if (this.ouch1 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch1);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch2:");
      if (this.ouch2 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch2);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch3:");
      if (this.ouch3 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch3);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class setTableProperty_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public setTableProperty_resultStandardScheme getScheme() {
        return new setTableProperty_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // OUCH1
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch1 = new AccumuloException();
                struct.ouch1.read(iprot);
                struct.setOuch1IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OUCH2
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch2 = new AccumuloSecurityException();
                struct.ouch2.read(iprot);
                struct.setOuch2IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // OUCH3
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch3 = new TableNotFoundException();
                struct.ouch3.read(iprot);
                struct.setOuch3IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, setTableProperty_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.ouch1 != null) {
          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
          struct.ouch1.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch2 != null) {
          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
          struct.ouch2.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch3 != null) {
          oprot.writeFieldBegin(OUCH3_FIELD_DESC);
          struct.ouch3.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class setTableProperty_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public setTableProperty_resultTupleScheme getScheme() {
        return new setTableProperty_resultTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetOuch2()) {
          optionals.set(1);
        }
        if (struct.isSetOuch3()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetOuch1()) {
          struct.ouch1.write(oprot);
        }
        if (struct.isSetOuch2()) {
          struct.ouch2.write(oprot);
        }
        if (struct.isSetOuch3()) {
          struct.ouch3.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, setTableProperty_result struct) throws org.apache.thrift.TException {
        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);
          struct.setOuch1IsSet(true);
        }
        if (incoming.get(1)) {
          struct.ouch2 = new AccumuloSecurityException();
          struct.ouch2.read(iprot);
          struct.setOuch2IsSet(true);
        }
        if (incoming.get(2)) {
          struct.ouch3 = new TableNotFoundException();
          struct.ouch3.read(iprot);
          struct.setOuch3IsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("splitRangeByTablets_args");

    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField 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 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 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 java.nio.ByteBuffer login; // required
    public java.lang.String tableName; // required
    public Range range; // required
    public int maxSplits; // 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"),
      RANGE((short)3, "range"),
      MAX_SPLITS((short)4, "maxSplits");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // LOGIN
            return LOGIN;
          case 2: // TABLE_NAME
            return TABLE_NAME;
          case 3: // RANGE
            return RANGE;
          case 4: // MAX_SPLITS
            return MAX_SPLITS;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __MAXSPLITS_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.RANGE, new org.apache.thrift.meta_data.FieldMetaData("range", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          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 = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(splitRangeByTablets_args.class, metaDataMap);
    }

    public splitRangeByTablets_args() {
    }

    public splitRangeByTablets_args(
      java.nio.ByteBuffer login,
      java.lang.String tableName,
      Range range,
      int maxSplits)
    {
      this();
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      this.tableName = tableName;
      this.range = range;
      this.maxSplits = maxSplits;
      setMaxSplitsIsSet(true);
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public splitRangeByTablets_args(splitRangeByTablets_args other) {
      __isset_bitfield = other.__isset_bitfield;
      if (other.isSetLogin()) {
        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
      }
      if (other.isSetTableName()) {
        this.tableName = other.tableName;
      }
      if (other.isSetRange()) {
        this.range = new Range(other.range);
      }
      this.maxSplits = other.maxSplits;
    }

    public splitRangeByTablets_args deepCopy() {
      return new splitRangeByTablets_args(this);
    }

    @Override
    public void clear() {
      this.login = null;
      this.tableName = null;
      this.range = null;
      setMaxSplitsIsSet(false);
      this.maxSplits = 0;
    }

    public byte[] getLogin() {
      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
      return login == null ? null : login.array();
    }

    public java.nio.ByteBuffer bufferForLogin() {
      return org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    public splitRangeByTablets_args setLogin(byte[] login) {
      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
      return this;
    }

    public splitRangeByTablets_args setLogin(java.nio.ByteBuffer login) {
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      return this;
    }

    public void unsetLogin() {
      this.login = null;
    }

    /** Returns true if field login is set (has been assigned a value) and false otherwise */
    public boolean isSetLogin() {
      return this.login != null;
    }

    public void setLoginIsSet(boolean value) {
      if (!value) {
        this.login = null;
      }
    }

    public java.lang.String getTableName() {
      return this.tableName;
    }

    public splitRangeByTablets_args setTableName(java.lang.String tableName) {
      this.tableName = tableName;
      return this;
    }

    public void unsetTableName() {
      this.tableName = null;
    }

    /** Returns true if field tableName is set (has been assigned a value) and false otherwise */
    public boolean isSetTableName() {
      return this.tableName != null;
    }

    public void setTableNameIsSet(boolean value) {
      if (!value) {
        this.tableName = null;
      }
    }

    public Range getRange() {
      return this.range;
    }

    public splitRangeByTablets_args setRange(Range range) {
      this.range = range;
      return this;
    }

    public void unsetRange() {
      this.range = null;
    }

    /** Returns true if field range is set (has been assigned a value) and false otherwise */
    public boolean isSetRange() {
      return this.range != null;
    }

    public void setRangeIsSet(boolean value) {
      if (!value) {
        this.range = null;
      }
    }

    public int getMaxSplits() {
      return this.maxSplits;
    }

    public splitRangeByTablets_args setMaxSplits(int maxSplits) {
      this.maxSplits = maxSplits;
      setMaxSplitsIsSet(true);
      return this;
    }

    public void unsetMaxSplits() {
      __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 org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __MAXSPLITS_ISSET_ID);
    }

    public void setMaxSplitsIsSet(boolean value) {
      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __MAXSPLITS_ISSET_ID, value);
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case LOGIN:
        if (value == null) {
          unsetLogin();
        } else {
          if (value instanceof byte[]) {
            setLogin((byte[])value);
          } else {
            setLogin((java.nio.ByteBuffer)value);
          }
        }
        break;

      case TABLE_NAME:
        if (value == null) {
          unsetTableName();
        } else {
          setTableName((java.lang.String)value);
        }
        break;

      case RANGE:
        if (value == null) {
          unsetRange();
        } else {
          setRange((Range)value);
        }
        break;

      case MAX_SPLITS:
        if (value == null) {
          unsetMaxSplits();
        } else {
          setMaxSplits((java.lang.Integer)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case LOGIN:
        return getLogin();

      case TABLE_NAME:
        return getTableName();

      case RANGE:
        return getRange();

      case MAX_SPLITS:
        return getMaxSplits();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case LOGIN:
        return isSetLogin();
      case TABLE_NAME:
        return isSetTableName();
      case RANGE:
        return isSetRange();
      case MAX_SPLITS:
        return isSetMaxSplits();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof splitRangeByTablets_args)
        return this.equals((splitRangeByTablets_args)that);
      return false;
    }

    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();
      if (this_present_login || that_present_login) {
        if (!(this_present_login && that_present_login))
          return false;
        if (!this.login.equals(that.login))
          return false;
      }

      boolean this_present_tableName = true && this.isSetTableName();
      boolean that_present_tableName = true && that.isSetTableName();
      if (this_present_tableName || that_present_tableName) {
        if (!(this_present_tableName && that_present_tableName))
          return false;
        if (!this.tableName.equals(that.tableName))
          return false;
      }

      boolean this_present_range = true && this.isSetRange();
      boolean that_present_range = true && that.isSetRange();
      if (this_present_range || that_present_range) {
        if (!(this_present_range && that_present_range))
          return false;
        if (!this.range.equals(that.range))
          return false;
      }

      boolean this_present_maxSplits = true;
      boolean that_present_maxSplits = true;
      if (this_present_maxSplits || that_present_maxSplits) {
        if (!(this_present_maxSplits && that_present_maxSplits))
          return false;
        if (this.maxSplits != that.maxSplits)
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
      if (isSetLogin())
        hashCode = hashCode * 8191 + login.hashCode();

      hashCode = hashCode * 8191 + ((isSetTableName()) ? 131071 : 524287);
      if (isSetTableName())
        hashCode = hashCode * 8191 + tableName.hashCode();

      hashCode = hashCode * 8191 + ((isSetRange()) ? 131071 : 524287);
      if (isSetRange())
        hashCode = hashCode * 8191 + range.hashCode();

      hashCode = hashCode * 8191 + maxSplits;

      return hashCode;
    }

    @Override
    public int compareTo(splitRangeByTablets_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLogin()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetTableName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.tableName, other.tableName);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetRange()).compareTo(other.isSetRange());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetRange()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.range, other.range);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetMaxSplits()).compareTo(other.isSetMaxSplits());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetMaxSplits()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.maxSplits, other.maxSplits);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("splitRangeByTablets_args(");
      boolean first = true;

      sb.append("login:");
      if (this.login == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.login, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("tableName:");
      if (this.tableName == null) {
        sb.append("null");
      } else {
        sb.append(this.tableName);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("range:");
      if (this.range == null) {
        sb.append("null");
      } else {
        sb.append(this.range);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("maxSplits:");
      sb.append(this.maxSplits);
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
      if (range != null) {
        range.validate();
      }
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, 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;
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class splitRangeByTablets_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public splitRangeByTablets_argsStandardScheme getScheme() {
        return new splitRangeByTablets_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // LOGIN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.login = iprot.readBinary();
                struct.setLoginIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // TABLE_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.tableName = iprot.readString();
                struct.setTableNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // RANGE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.range = new Range();
                struct.range.read(iprot);
                struct.setRangeIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // MAX_SPLITS
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.maxSplits = iprot.readI32();
                struct.setMaxSplitsIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, splitRangeByTablets_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.login != null) {
          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
          oprot.writeBinary(struct.login);
          oprot.writeFieldEnd();
        }
        if (struct.tableName != null) {
          oprot.writeFieldBegin(TABLE_NAME_FIELD_DESC);
          oprot.writeString(struct.tableName);
          oprot.writeFieldEnd();
        }
        if (struct.range != null) {
          oprot.writeFieldBegin(RANGE_FIELD_DESC);
          struct.range.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldBegin(MAX_SPLITS_FIELD_DESC);
        oprot.writeI32(struct.maxSplits);
        oprot.writeFieldEnd();
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    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 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 {
        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);
        }
        if (struct.isSetTableName()) {
          optionals.set(1);
        }
        if (struct.isSetRange()) {
          optionals.set(2);
        }
        if (struct.isSetMaxSplits()) {
          optionals.set(3);
        }
        oprot.writeBitSet(optionals, 4);
        if (struct.isSetLogin()) {
          oprot.writeBinary(struct.login);
        }
        if (struct.isSetTableName()) {
          oprot.writeString(struct.tableName);
        }
        if (struct.isSetRange()) {
          struct.range.write(oprot);
        }
        if (struct.isSetMaxSplits()) {
          oprot.writeI32(struct.maxSplits);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, splitRangeByTablets_args struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.tableName = iprot.readString();
          struct.setTableNameIsSet(true);
        }
        if (incoming.get(2)) {
          struct.range = new Range();
          struct.range.read(iprot);
          struct.setRangeIsSet(true);
        }
        if (incoming.get(3)) {
          struct.maxSplits = iprot.readI32();
          struct.setMaxSplitsIsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("splitRangeByTablets_result");

    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 org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField OUCH3_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch3", org.apache.thrift.protocol.TType.STRUCT, (short)3);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new splitRangeByTablets_resultStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new splitRangeByTablets_resultTupleSchemeFactory();

    public java.util.Set<Range> success; // required
    public AccumuloException ouch1; // required
    public AccumuloSecurityException ouch2; // required
    public TableNotFoundException ouch3; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      OUCH1((short)1, "ouch1"),
      OUCH2((short)2, "ouch2"),
      OUCH3((short)3, "ouch3");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // OUCH1
            return OUCH1;
          case 2: // OUCH2
            return OUCH2;
          case 3: // OUCH3
            return OUCH3;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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.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.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);
    }

    public splitRangeByTablets_result() {
    }

    public splitRangeByTablets_result(
      java.util.Set<Range> success,
      AccumuloException ouch1,
      AccumuloSecurityException ouch2,
      TableNotFoundException ouch3)
    {
      this();
      this.success = success;
      this.ouch1 = ouch1;
      this.ouch2 = ouch2;
      this.ouch3 = ouch3;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public splitRangeByTablets_result(splitRangeByTablets_result other) {
      if (other.isSetSuccess()) {
        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));
        }
        this.success = __this__success;
      }
      if (other.isSetOuch1()) {
        this.ouch1 = new AccumuloException(other.ouch1);
      }
      if (other.isSetOuch2()) {
        this.ouch2 = new AccumuloSecurityException(other.ouch2);
      }
      if (other.isSetOuch3()) {
        this.ouch3 = new TableNotFoundException(other.ouch3);
      }
    }

    public splitRangeByTablets_result deepCopy() {
      return new splitRangeByTablets_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ouch1 = null;
      this.ouch2 = null;
      this.ouch3 = null;
    }

    public int getSuccessSize() {
      return (this.success == null) ? 0 : this.success.size();
    }

    public java.util.Iterator<Range> getSuccessIterator() {
      return (this.success == null) ? null : this.success.iterator();
    }

    public void addToSuccess(Range elem) {
      if (this.success == null) {
        this.success = new java.util.HashSet<Range>();
      }
      this.success.add(elem);
    }

    public java.util.Set<Range> getSuccess() {
      return this.success;
    }

    public splitRangeByTablets_result setSuccess(java.util.Set<Range> success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return this.success != null;
    }

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public AccumuloException getOuch1() {
      return this.ouch1;
    }

    public splitRangeByTablets_result setOuch1(AccumuloException ouch1) {
      this.ouch1 = ouch1;
      return this;
    }

    public void unsetOuch1() {
      this.ouch1 = null;
    }

    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch1() {
      return this.ouch1 != null;
    }

    public void setOuch1IsSet(boolean value) {
      if (!value) {
        this.ouch1 = null;
      }
    }

    public AccumuloSecurityException getOuch2() {
      return this.ouch2;
    }

    public splitRangeByTablets_result setOuch2(AccumuloSecurityException ouch2) {
      this.ouch2 = ouch2;
      return this;
    }

    public void unsetOuch2() {
      this.ouch2 = null;
    }

    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch2() {
      return this.ouch2 != null;
    }

    public void setOuch2IsSet(boolean value) {
      if (!value) {
        this.ouch2 = null;
      }
    }

    public TableNotFoundException getOuch3() {
      return this.ouch3;
    }

    public splitRangeByTablets_result setOuch3(TableNotFoundException ouch3) {
      this.ouch3 = ouch3;
      return this;
    }

    public void unsetOuch3() {
      this.ouch3 = null;
    }

    /** Returns true if field ouch3 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch3() {
      return this.ouch3 != null;
    }

    public void setOuch3IsSet(boolean value) {
      if (!value) {
        this.ouch3 = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.util.Set<Range>)value);
        }
        break;

      case OUCH1:
        if (value == null) {
          unsetOuch1();
        } else {
          setOuch1((AccumuloException)value);
        }
        break;

      case OUCH2:
        if (value == null) {
          unsetOuch2();
        } else {
          setOuch2((AccumuloSecurityException)value);
        }
        break;

      case OUCH3:
        if (value == null) {
          unsetOuch3();
        } else {
          setOuch3((TableNotFoundException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case OUCH1:
        return getOuch1();

      case OUCH2:
        return getOuch2();

      case OUCH3:
        return getOuch3();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case OUCH1:
        return isSetOuch1();
      case OUCH2:
        return isSetOuch2();
      case OUCH3:
        return isSetOuch3();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof splitRangeByTablets_result)
        return this.equals((splitRangeByTablets_result)that);
      return false;
    }

    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();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ouch1 = true && this.isSetOuch1();
      boolean that_present_ouch1 = true && that.isSetOuch1();
      if (this_present_ouch1 || that_present_ouch1) {
        if (!(this_present_ouch1 && that_present_ouch1))
          return false;
        if (!this.ouch1.equals(that.ouch1))
          return false;
      }

      boolean this_present_ouch2 = true && this.isSetOuch2();
      boolean that_present_ouch2 = true && that.isSetOuch2();
      if (this_present_ouch2 || that_present_ouch2) {
        if (!(this_present_ouch2 && that_present_ouch2))
          return false;
        if (!this.ouch2.equals(that.ouch2))
          return false;
      }

      boolean this_present_ouch3 = true && this.isSetOuch3();
      boolean that_present_ouch3 = true && that.isSetOuch3();
      if (this_present_ouch3 || that_present_ouch3) {
        if (!(this_present_ouch3 && that_present_ouch3))
          return false;
        if (!this.ouch3.equals(that.ouch3))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
      if (isSetSuccess())
        hashCode = hashCode * 8191 + success.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
      if (isSetOuch1())
        hashCode = hashCode * 8191 + ouch1.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
      if (isSetOuch2())
        hashCode = hashCode * 8191 + ouch2.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
      if (isSetOuch3())
        hashCode = hashCode * 8191 + ouch3.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(splitRangeByTablets_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch1()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch2()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch3()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch3, other.ouch3);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("splitRangeByTablets_result(");
      boolean first = true;

      sb.append("success:");
      if (this.success == null) {
        sb.append("null");
      } else {
        sb.append(this.success);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch1:");
      if (this.ouch1 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch1);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch2:");
      if (this.ouch2 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch2);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch3:");
      if (this.ouch3 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch3);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class splitRangeByTablets_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public splitRangeByTablets_resultStandardScheme getScheme() {
        return new splitRangeByTablets_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.SET) {
                {
                  org.apache.thrift.protocol.TSet _set346 = iprot.readSetBegin();
                  struct.success = new java.util.HashSet<Range>(2*_set346.size);
                  Range _elem347;
                  for (int _i348 = 0; _i348 < _set346.size; ++_i348)
                  {
                    _elem347 = new Range();
                    _elem347.read(iprot);
                    struct.success.add(_elem347);
                  }
                  iprot.readSetEnd();
                }
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // OUCH1
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch1 = new AccumuloException();
                struct.ouch1.read(iprot);
                struct.setOuch1IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OUCH2
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch2 = new AccumuloSecurityException();
                struct.ouch2.read(iprot);
                struct.setOuch2IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // OUCH3
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch3 = new TableNotFoundException();
                struct.ouch3.read(iprot);
                struct.setOuch3IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, splitRangeByTablets_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          {
            oprot.writeSetBegin(new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRUCT, struct.success.size()));
            for (Range _iter349 : struct.success)
            {
              _iter349.write(oprot);
            }
            oprot.writeSetEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.ouch1 != null) {
          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
          struct.ouch1.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch2 != null) {
          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
          struct.ouch2.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch3 != null) {
          oprot.writeFieldBegin(OUCH3_FIELD_DESC);
          struct.ouch3.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class splitRangeByTablets_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public splitRangeByTablets_resultTupleScheme getScheme() {
        return new splitRangeByTablets_resultTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetOuch1()) {
          optionals.set(1);
        }
        if (struct.isSetOuch2()) {
          optionals.set(2);
        }
        if (struct.isSetOuch3()) {
          optionals.set(3);
        }
        oprot.writeBitSet(optionals, 4);
        if (struct.isSetSuccess()) {
          {
            oprot.writeI32(struct.success.size());
            for (Range _iter350 : struct.success)
            {
              _iter350.write(oprot);
            }
          }
        }
        if (struct.isSetOuch1()) {
          struct.ouch1.write(oprot);
        }
        if (struct.isSetOuch2()) {
          struct.ouch2.write(oprot);
        }
        if (struct.isSetOuch3()) {
          struct.ouch3.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, splitRangeByTablets_result struct) throws org.apache.thrift.TException {
        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 java.util.HashSet<Range>(2*_set351.size);
            Range _elem352;
            for (int _i353 = 0; _i353 < _set351.size; ++_i353)
            {
              _elem352 = new Range();
              _elem352.read(iprot);
              struct.success.add(_elem352);
            }
          }
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ouch1 = new AccumuloException();
          struct.ouch1.read(iprot);
          struct.setOuch1IsSet(true);
        }
        if (incoming.get(2)) {
          struct.ouch2 = new AccumuloSecurityException();
          struct.ouch2.read(iprot);
          struct.setOuch2IsSet(true);
        }
        if (incoming.get(3)) {
          struct.ouch3 = new TableNotFoundException();
          struct.ouch3.read(iprot);
          struct.setOuch3IsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("tableExists_args");

    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField 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.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new tableExists_argsStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new tableExists_argsTupleSchemeFactory();

    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 java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // LOGIN
            return LOGIN;
          case 2: // TABLE_NAME
            return TABLE_NAME;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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 = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(tableExists_args.class, metaDataMap);
    }

    public tableExists_args() {
    }

    public tableExists_args(
      java.nio.ByteBuffer login,
      java.lang.String tableName)
    {
      this();
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      this.tableName = tableName;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public tableExists_args(tableExists_args other) {
      if (other.isSetLogin()) {
        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
      }
      if (other.isSetTableName()) {
        this.tableName = other.tableName;
      }
    }

    public tableExists_args deepCopy() {
      return new tableExists_args(this);
    }

    @Override
    public void clear() {
      this.login = null;
      this.tableName = null;
    }

    public byte[] getLogin() {
      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
      return login == null ? null : login.array();
    }

    public java.nio.ByteBuffer bufferForLogin() {
      return org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    public tableExists_args setLogin(byte[] login) {
      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
      return this;
    }

    public tableExists_args setLogin(java.nio.ByteBuffer login) {
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      return this;
    }

    public void unsetLogin() {
      this.login = null;
    }

    /** Returns true if field login is set (has been assigned a value) and false otherwise */
    public boolean isSetLogin() {
      return this.login != null;
    }

    public void setLoginIsSet(boolean value) {
      if (!value) {
        this.login = null;
      }
    }

    public java.lang.String getTableName() {
      return this.tableName;
    }

    public tableExists_args setTableName(java.lang.String tableName) {
      this.tableName = tableName;
      return this;
    }

    public void unsetTableName() {
      this.tableName = null;
    }

    /** Returns true if field tableName is set (has been assigned a value) and false otherwise */
    public boolean isSetTableName() {
      return this.tableName != null;
    }

    public void setTableNameIsSet(boolean value) {
      if (!value) {
        this.tableName = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case LOGIN:
        if (value == null) {
          unsetLogin();
        } else {
          if (value instanceof byte[]) {
            setLogin((byte[])value);
          } else {
            setLogin((java.nio.ByteBuffer)value);
          }
        }
        break;

      case TABLE_NAME:
        if (value == null) {
          unsetTableName();
        } else {
          setTableName((java.lang.String)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case LOGIN:
        return getLogin();

      case TABLE_NAME:
        return getTableName();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case LOGIN:
        return isSetLogin();
      case TABLE_NAME:
        return isSetTableName();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof tableExists_args)
        return this.equals((tableExists_args)that);
      return false;
    }

    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();
      if (this_present_login || that_present_login) {
        if (!(this_present_login && that_present_login))
          return false;
        if (!this.login.equals(that.login))
          return false;
      }

      boolean this_present_tableName = true && this.isSetTableName();
      boolean that_present_tableName = true && that.isSetTableName();
      if (this_present_tableName || that_present_tableName) {
        if (!(this_present_tableName && that_present_tableName))
          return false;
        if (!this.tableName.equals(that.tableName))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
      if (isSetLogin())
        hashCode = hashCode * 8191 + login.hashCode();

      hashCode = hashCode * 8191 + ((isSetTableName()) ? 131071 : 524287);
      if (isSetTableName())
        hashCode = hashCode * 8191 + tableName.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(tableExists_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLogin()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetTableName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.tableName, other.tableName);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("tableExists_args(");
      boolean first = true;

      sb.append("login:");
      if (this.login == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.login, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("tableName:");
      if (this.tableName == null) {
        sb.append("null");
      } else {
        sb.append(this.tableName);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class tableExists_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public tableExists_argsStandardScheme getScheme() {
        return new tableExists_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // LOGIN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.login = iprot.readBinary();
                struct.setLoginIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // TABLE_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.tableName = iprot.readString();
                struct.setTableNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, tableExists_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.login != null) {
          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
          oprot.writeBinary(struct.login);
          oprot.writeFieldEnd();
        }
        if (struct.tableName != null) {
          oprot.writeFieldBegin(TABLE_NAME_FIELD_DESC);
          oprot.writeString(struct.tableName);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    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 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 {
        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);
        }
        if (struct.isSetTableName()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetLogin()) {
          oprot.writeBinary(struct.login);
        }
        if (struct.isSetTableName()) {
          oprot.writeString(struct.tableName);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, tableExists_args struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.tableName = iprot.readString();
          struct.setTableNameIsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("tableExists_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.BOOL, (short)0);

    private static final org.apache.thrift.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

    /** 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 java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __SUCCESS_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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 = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(tableExists_result.class, metaDataMap);
    }

    public tableExists_result() {
    }

    public tableExists_result(
      boolean success)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public tableExists_result(tableExists_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
    }

    public tableExists_result deepCopy() {
      return new tableExists_result(this);
    }

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public tableExists_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

    public void unsetSuccess() {
      __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 org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    public void setSuccessIsSet(boolean value) {
      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.lang.Boolean)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return isSuccess();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof tableExists_result)
        return this.equals((tableExists_result)that);
      return false;
    }

    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;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((success) ? 131071 : 524287);

      return hashCode;
    }

    @Override
    public int compareTo(tableExists_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("tableExists_result(");
      boolean first = true;

      sb.append("success:");
      sb.append(this.success);
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, 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;
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class tableExists_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public tableExists_resultStandardScheme getScheme() {
        return new tableExists_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
                struct.success = iprot.readBool();
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, tableExists_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.isSetSuccess()) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          oprot.writeBool(struct.success);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    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 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 {
        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);
        }
        oprot.writeBitSet(optionals, 1);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, tableExists_result struct) throws org.apache.thrift.TException {
        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);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("tableIdMap_args");

    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new tableIdMap_argsStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new tableIdMap_argsTupleSchemeFactory();

    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 java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // LOGIN
            return LOGIN;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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 = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(tableIdMap_args.class, metaDataMap);
    }

    public tableIdMap_args() {
    }

    public tableIdMap_args(
      java.nio.ByteBuffer login)
    {
      this();
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public tableIdMap_args(tableIdMap_args other) {
      if (other.isSetLogin()) {
        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
      }
    }

    public tableIdMap_args deepCopy() {
      return new tableIdMap_args(this);
    }

    @Override
    public void clear() {
      this.login = null;
    }

    public byte[] getLogin() {
      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
      return login == null ? null : login.array();
    }

    public java.nio.ByteBuffer bufferForLogin() {
      return org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    public tableIdMap_args setLogin(byte[] login) {
      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
      return this;
    }

    public tableIdMap_args setLogin(java.nio.ByteBuffer login) {
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      return this;
    }

    public void unsetLogin() {
      this.login = null;
    }

    /** Returns true if field login is set (has been assigned a value) and false otherwise */
    public boolean isSetLogin() {
      return this.login != null;
    }

    public void setLoginIsSet(boolean value) {
      if (!value) {
        this.login = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case LOGIN:
        if (value == null) {
          unsetLogin();
        } else {
          if (value instanceof byte[]) {
            setLogin((byte[])value);
          } else {
            setLogin((java.nio.ByteBuffer)value);
          }
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case LOGIN:
        return getLogin();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case LOGIN:
        return isSetLogin();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof tableIdMap_args)
        return this.equals((tableIdMap_args)that);
      return false;
    }

    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();
      if (this_present_login || that_present_login) {
        if (!(this_present_login && that_present_login))
          return false;
        if (!this.login.equals(that.login))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
      if (isSetLogin())
        hashCode = hashCode * 8191 + login.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(tableIdMap_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLogin()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("tableIdMap_args(");
      boolean first = true;

      sb.append("login:");
      if (this.login == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.login, sb);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class tableIdMap_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public tableIdMap_argsStandardScheme getScheme() {
        return new tableIdMap_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // LOGIN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.login = iprot.readBinary();
                struct.setLoginIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, tableIdMap_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.login != null) {
          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
          oprot.writeBinary(struct.login);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class tableIdMap_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public tableIdMap_argsTupleScheme getScheme() {
        return new tableIdMap_argsTupleScheme();
      }
    }

    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 {
        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);
        }
        oprot.writeBitSet(optionals, 1);
        if (struct.isSetLogin()) {
          oprot.writeBinary(struct.login);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, tableIdMap_args struct) throws org.apache.thrift.TException {
        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);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("tableIdMap_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.MAP, (short)0);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new tableIdMap_resultStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new tableIdMap_resultTupleSchemeFactory();

    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 java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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 = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(tableIdMap_result.class, metaDataMap);
    }

    public tableIdMap_result() {
    }

    public tableIdMap_result(
      java.util.Map<java.lang.String,java.lang.String> success)
    {
      this();
      this.success = success;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public tableIdMap_result(tableIdMap_result other) {
      if (other.isSetSuccess()) {
        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;
      }
    }

    public tableIdMap_result deepCopy() {
      return new tableIdMap_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
    }

    public int getSuccessSize() {
      return (this.success == null) ? 0 : this.success.size();
    }

    public void putToSuccess(java.lang.String key, java.lang.String val) {
      if (this.success == null) {
        this.success = new java.util.HashMap<java.lang.String,java.lang.String>();
      }
      this.success.put(key, val);
    }

    public java.util.Map<java.lang.String,java.lang.String> getSuccess() {
      return this.success;
    }

    public tableIdMap_result setSuccess(java.util.Map<java.lang.String,java.lang.String> success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return this.success != null;
    }

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.util.Map<java.lang.String,java.lang.String>)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof tableIdMap_result)
        return this.equals((tableIdMap_result)that);
      return false;
    }

    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();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
      if (isSetSuccess())
        hashCode = hashCode * 8191 + success.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(tableIdMap_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("tableIdMap_result(");
      boolean first = true;

      sb.append("success:");
      if (this.success == null) {
        sb.append("null");
      } else {
        sb.append(this.success);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class tableIdMap_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public tableIdMap_resultStandardScheme getScheme() {
        return new tableIdMap_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.MAP) {
                {
                  org.apache.thrift.protocol.TMap _map354 = iprot.readMapBegin();
                  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();
                    _val356 = iprot.readString();
                    struct.success.put(_key355, _val356);
                  }
                  iprot.readMapEnd();
                }
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, tableIdMap_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          {
            oprot.writeMapBegin(new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.STRING, struct.success.size()));
            for (java.util.Map.Entry<java.lang.String, java.lang.String> _iter358 : struct.success.entrySet())
            {
              oprot.writeString(_iter358.getKey());
              oprot.writeString(_iter358.getValue());
            }
            oprot.writeMapEnd();
          }
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    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 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 {
        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);
        }
        oprot.writeBitSet(optionals, 1);
        if (struct.isSetSuccess()) {
          {
            oprot.writeI32(struct.success.size());
            for (java.util.Map.Entry<java.lang.String, java.lang.String> _iter359 : struct.success.entrySet())
            {
              oprot.writeString(_iter359.getKey());
              oprot.writeString(_iter359.getValue());
            }
          }
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, tableIdMap_result struct) throws org.apache.thrift.TException {
        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 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();
              _val362 = iprot.readString();
              struct.success.put(_key361, _val362);
            }
          }
          struct.setSuccessIsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("testTableClassLoad_args");

    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField 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 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 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 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 {
      LOGIN((short)1, "login"),
      TABLE_NAME((short)2, "tableName"),
      CLASS_NAME((short)3, "className"),
      AS_TYPE_NAME((short)4, "asTypeName");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // LOGIN
            return LOGIN;
          case 2: // TABLE_NAME
            return TABLE_NAME;
          case 3: // CLASS_NAME
            return CLASS_NAME;
          case 4: // AS_TYPE_NAME
            return AS_TYPE_NAME;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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 = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(testTableClassLoad_args.class, metaDataMap);
    }

    public testTableClassLoad_args() {
    }

    public testTableClassLoad_args(
      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);
      this.tableName = tableName;
      this.className = className;
      this.asTypeName = asTypeName;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public testTableClassLoad_args(testTableClassLoad_args other) {
      if (other.isSetLogin()) {
        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
      }
      if (other.isSetTableName()) {
        this.tableName = other.tableName;
      }
      if (other.isSetClassName()) {
        this.className = other.className;
      }
      if (other.isSetAsTypeName()) {
        this.asTypeName = other.asTypeName;
      }
    }

    public testTableClassLoad_args deepCopy() {
      return new testTableClassLoad_args(this);
    }

    @Override
    public void clear() {
      this.login = null;
      this.tableName = null;
      this.className = null;
      this.asTypeName = null;
    }

    public byte[] getLogin() {
      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
      return login == null ? null : login.array();
    }

    public java.nio.ByteBuffer bufferForLogin() {
      return org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    public testTableClassLoad_args setLogin(byte[] login) {
      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
      return this;
    }

    public testTableClassLoad_args setLogin(java.nio.ByteBuffer login) {
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      return this;
    }

    public void unsetLogin() {
      this.login = null;
    }

    /** Returns true if field login is set (has been assigned a value) and false otherwise */
    public boolean isSetLogin() {
      return this.login != null;
    }

    public void setLoginIsSet(boolean value) {
      if (!value) {
        this.login = null;
      }
    }

    public java.lang.String getTableName() {
      return this.tableName;
    }

    public testTableClassLoad_args setTableName(java.lang.String tableName) {
      this.tableName = tableName;
      return this;
    }

    public void unsetTableName() {
      this.tableName = null;
    }

    /** Returns true if field tableName is set (has been assigned a value) and false otherwise */
    public boolean isSetTableName() {
      return this.tableName != null;
    }

    public void setTableNameIsSet(boolean value) {
      if (!value) {
        this.tableName = null;
      }
    }

    public java.lang.String getClassName() {
      return this.className;
    }

    public testTableClassLoad_args setClassName(java.lang.String className) {
      this.className = className;
      return this;
    }

    public void unsetClassName() {
      this.className = null;
    }

    /** Returns true if field className is set (has been assigned a value) and false otherwise */
    public boolean isSetClassName() {
      return this.className != null;
    }

    public void setClassNameIsSet(boolean value) {
      if (!value) {
        this.className = null;
      }
    }

    public java.lang.String getAsTypeName() {
      return this.asTypeName;
    }

    public testTableClassLoad_args setAsTypeName(java.lang.String asTypeName) {
      this.asTypeName = asTypeName;
      return this;
    }

    public void unsetAsTypeName() {
      this.asTypeName = null;
    }

    /** Returns true if field asTypeName is set (has been assigned a value) and false otherwise */
    public boolean isSetAsTypeName() {
      return this.asTypeName != null;
    }

    public void setAsTypeNameIsSet(boolean value) {
      if (!value) {
        this.asTypeName = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case LOGIN:
        if (value == null) {
          unsetLogin();
        } else {
          if (value instanceof byte[]) {
            setLogin((byte[])value);
          } else {
            setLogin((java.nio.ByteBuffer)value);
          }
        }
        break;

      case TABLE_NAME:
        if (value == null) {
          unsetTableName();
        } else {
          setTableName((java.lang.String)value);
        }
        break;

      case CLASS_NAME:
        if (value == null) {
          unsetClassName();
        } else {
          setClassName((java.lang.String)value);
        }
        break;

      case AS_TYPE_NAME:
        if (value == null) {
          unsetAsTypeName();
        } else {
          setAsTypeName((java.lang.String)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case LOGIN:
        return getLogin();

      case TABLE_NAME:
        return getTableName();

      case CLASS_NAME:
        return getClassName();

      case AS_TYPE_NAME:
        return getAsTypeName();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case LOGIN:
        return isSetLogin();
      case TABLE_NAME:
        return isSetTableName();
      case CLASS_NAME:
        return isSetClassName();
      case AS_TYPE_NAME:
        return isSetAsTypeName();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof testTableClassLoad_args)
        return this.equals((testTableClassLoad_args)that);
      return false;
    }

    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();
      if (this_present_login || that_present_login) {
        if (!(this_present_login && that_present_login))
          return false;
        if (!this.login.equals(that.login))
          return false;
      }

      boolean this_present_tableName = true && this.isSetTableName();
      boolean that_present_tableName = true && that.isSetTableName();
      if (this_present_tableName || that_present_tableName) {
        if (!(this_present_tableName && that_present_tableName))
          return false;
        if (!this.tableName.equals(that.tableName))
          return false;
      }

      boolean this_present_className = true && this.isSetClassName();
      boolean that_present_className = true && that.isSetClassName();
      if (this_present_className || that_present_className) {
        if (!(this_present_className && that_present_className))
          return false;
        if (!this.className.equals(that.className))
          return false;
      }

      boolean this_present_asTypeName = true && this.isSetAsTypeName();
      boolean that_present_asTypeName = true && that.isSetAsTypeName();
      if (this_present_asTypeName || that_present_asTypeName) {
        if (!(this_present_asTypeName && that_present_asTypeName))
          return false;
        if (!this.asTypeName.equals(that.asTypeName))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
      if (isSetLogin())
        hashCode = hashCode * 8191 + login.hashCode();

      hashCode = hashCode * 8191 + ((isSetTableName()) ? 131071 : 524287);
      if (isSetTableName())
        hashCode = hashCode * 8191 + tableName.hashCode();

      hashCode = hashCode * 8191 + ((isSetClassName()) ? 131071 : 524287);
      if (isSetClassName())
        hashCode = hashCode * 8191 + className.hashCode();

      hashCode = hashCode * 8191 + ((isSetAsTypeName()) ? 131071 : 524287);
      if (isSetAsTypeName())
        hashCode = hashCode * 8191 + asTypeName.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(testTableClassLoad_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLogin()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetTableName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.tableName, other.tableName);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetClassName()).compareTo(other.isSetClassName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetClassName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.className, other.className);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetAsTypeName()).compareTo(other.isSetAsTypeName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAsTypeName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.asTypeName, other.asTypeName);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("testTableClassLoad_args(");
      boolean first = true;

      sb.append("login:");
      if (this.login == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.login, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("tableName:");
      if (this.tableName == null) {
        sb.append("null");
      } else {
        sb.append(this.tableName);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("className:");
      if (this.className == null) {
        sb.append("null");
      } else {
        sb.append(this.className);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("asTypeName:");
      if (this.asTypeName == null) {
        sb.append("null");
      } else {
        sb.append(this.asTypeName);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class testTableClassLoad_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public testTableClassLoad_argsStandardScheme getScheme() {
        return new testTableClassLoad_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // LOGIN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.login = iprot.readBinary();
                struct.setLoginIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // TABLE_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.tableName = iprot.readString();
                struct.setTableNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // CLASS_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.className = iprot.readString();
                struct.setClassNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // AS_TYPE_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.asTypeName = iprot.readString();
                struct.setAsTypeNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, testTableClassLoad_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.login != null) {
          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
          oprot.writeBinary(struct.login);
          oprot.writeFieldEnd();
        }
        if (struct.tableName != null) {
          oprot.writeFieldBegin(TABLE_NAME_FIELD_DESC);
          oprot.writeString(struct.tableName);
          oprot.writeFieldEnd();
        }
        if (struct.className != null) {
          oprot.writeFieldBegin(CLASS_NAME_FIELD_DESC);
          oprot.writeString(struct.className);
          oprot.writeFieldEnd();
        }
        if (struct.asTypeName != null) {
          oprot.writeFieldBegin(AS_TYPE_NAME_FIELD_DESC);
          oprot.writeString(struct.asTypeName);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class testTableClassLoad_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public testTableClassLoad_argsTupleScheme getScheme() {
        return new testTableClassLoad_argsTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetTableName()) {
          optionals.set(1);
        }
        if (struct.isSetClassName()) {
          optionals.set(2);
        }
        if (struct.isSetAsTypeName()) {
          optionals.set(3);
        }
        oprot.writeBitSet(optionals, 4);
        if (struct.isSetLogin()) {
          oprot.writeBinary(struct.login);
        }
        if (struct.isSetTableName()) {
          oprot.writeString(struct.tableName);
        }
        if (struct.isSetClassName()) {
          oprot.writeString(struct.className);
        }
        if (struct.isSetAsTypeName()) {
          oprot.writeString(struct.asTypeName);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, testTableClassLoad_args struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.tableName = iprot.readString();
          struct.setTableNameIsSet(true);
        }
        if (incoming.get(2)) {
          struct.className = iprot.readString();
          struct.setClassNameIsSet(true);
        }
        if (incoming.get(3)) {
          struct.asTypeName = iprot.readString();
          struct.setAsTypeNameIsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("testTableClassLoad_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.BOOL, (short)0);
    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField OUCH3_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch3", org.apache.thrift.protocol.TType.STRUCT, (short)3);

    private static final 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
    public AccumuloSecurityException ouch2; // required
    public TableNotFoundException ouch3; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      OUCH1((short)1, "ouch1"),
      OUCH2((short)2, "ouch2"),
      OUCH3((short)3, "ouch3");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // OUCH1
            return OUCH1;
          case 2: // OUCH2
            return OUCH2;
          case 3: // OUCH3
            return OUCH3;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __SUCCESS_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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.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.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);
    }

    public testTableClassLoad_result() {
    }

    public testTableClassLoad_result(
      boolean success,
      AccumuloException ouch1,
      AccumuloSecurityException ouch2,
      TableNotFoundException ouch3)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
      this.ouch1 = ouch1;
      this.ouch2 = ouch2;
      this.ouch3 = ouch3;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public testTableClassLoad_result(testTableClassLoad_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
      if (other.isSetOuch1()) {
        this.ouch1 = new AccumuloException(other.ouch1);
      }
      if (other.isSetOuch2()) {
        this.ouch2 = new AccumuloSecurityException(other.ouch2);
      }
      if (other.isSetOuch3()) {
        this.ouch3 = new TableNotFoundException(other.ouch3);
      }
    }

    public testTableClassLoad_result deepCopy() {
      return new testTableClassLoad_result(this);
    }

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
      this.ouch1 = null;
      this.ouch2 = null;
      this.ouch3 = null;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public testTableClassLoad_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

    public void unsetSuccess() {
      __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 org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    public void setSuccessIsSet(boolean value) {
      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
    }

    public AccumuloException getOuch1() {
      return this.ouch1;
    }

    public testTableClassLoad_result setOuch1(AccumuloException ouch1) {
      this.ouch1 = ouch1;
      return this;
    }

    public void unsetOuch1() {
      this.ouch1 = null;
    }

    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch1() {
      return this.ouch1 != null;
    }

    public void setOuch1IsSet(boolean value) {
      if (!value) {
        this.ouch1 = null;
      }
    }

    public AccumuloSecurityException getOuch2() {
      return this.ouch2;
    }

    public testTableClassLoad_result setOuch2(AccumuloSecurityException ouch2) {
      this.ouch2 = ouch2;
      return this;
    }

    public void unsetOuch2() {
      this.ouch2 = null;
    }

    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch2() {
      return this.ouch2 != null;
    }

    public void setOuch2IsSet(boolean value) {
      if (!value) {
        this.ouch2 = null;
      }
    }

    public TableNotFoundException getOuch3() {
      return this.ouch3;
    }

    public testTableClassLoad_result setOuch3(TableNotFoundException ouch3) {
      this.ouch3 = ouch3;
      return this;
    }

    public void unsetOuch3() {
      this.ouch3 = null;
    }

    /** Returns true if field ouch3 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch3() {
      return this.ouch3 != null;
    }

    public void setOuch3IsSet(boolean value) {
      if (!value) {
        this.ouch3 = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.lang.Boolean)value);
        }
        break;

      case OUCH1:
        if (value == null) {
          unsetOuch1();
        } else {
          setOuch1((AccumuloException)value);
        }
        break;

      case OUCH2:
        if (value == null) {
          unsetOuch2();
        } else {
          setOuch2((AccumuloSecurityException)value);
        }
        break;

      case OUCH3:
        if (value == null) {
          unsetOuch3();
        } else {
          setOuch3((TableNotFoundException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return isSuccess();

      case OUCH1:
        return getOuch1();

      case OUCH2:
        return getOuch2();

      case OUCH3:
        return getOuch3();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case OUCH1:
        return isSetOuch1();
      case OUCH2:
        return isSetOuch2();
      case OUCH3:
        return isSetOuch3();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof testTableClassLoad_result)
        return this.equals((testTableClassLoad_result)that);
      return false;
    }

    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;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      boolean this_present_ouch1 = true && this.isSetOuch1();
      boolean that_present_ouch1 = true && that.isSetOuch1();
      if (this_present_ouch1 || that_present_ouch1) {
        if (!(this_present_ouch1 && that_present_ouch1))
          return false;
        if (!this.ouch1.equals(that.ouch1))
          return false;
      }

      boolean this_present_ouch2 = true && this.isSetOuch2();
      boolean that_present_ouch2 = true && that.isSetOuch2();
      if (this_present_ouch2 || that_present_ouch2) {
        if (!(this_present_ouch2 && that_present_ouch2))
          return false;
        if (!this.ouch2.equals(that.ouch2))
          return false;
      }

      boolean this_present_ouch3 = true && this.isSetOuch3();
      boolean that_present_ouch3 = true && that.isSetOuch3();
      if (this_present_ouch3 || that_present_ouch3) {
        if (!(this_present_ouch3 && that_present_ouch3))
          return false;
        if (!this.ouch3.equals(that.ouch3))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((success) ? 131071 : 524287);

      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
      if (isSetOuch1())
        hashCode = hashCode * 8191 + ouch1.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
      if (isSetOuch2())
        hashCode = hashCode * 8191 + ouch2.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
      if (isSetOuch3())
        hashCode = hashCode * 8191 + ouch3.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(testTableClassLoad_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch1()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch2()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch3()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch3, other.ouch3);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("testTableClassLoad_result(");
      boolean first = true;

      sb.append("success:");
      sb.append(this.success);
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch1:");
      if (this.ouch1 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch1);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch2:");
      if (this.ouch2 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch2);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch3:");
      if (this.ouch3 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch3);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, 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;
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class testTableClassLoad_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public testTableClassLoad_resultStandardScheme getScheme() {
        return new testTableClassLoad_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
                struct.success = iprot.readBool();
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // OUCH1
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch1 = new AccumuloException();
                struct.ouch1.read(iprot);
                struct.setOuch1IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OUCH2
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch2 = new AccumuloSecurityException();
                struct.ouch2.read(iprot);
                struct.setOuch2IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // OUCH3
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch3 = new TableNotFoundException();
                struct.ouch3.read(iprot);
                struct.setOuch3IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, testTableClassLoad_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.isSetSuccess()) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          oprot.writeBool(struct.success);
          oprot.writeFieldEnd();
        }
        if (struct.ouch1 != null) {
          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
          struct.ouch1.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch2 != null) {
          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
          struct.ouch2.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch3 != null) {
          oprot.writeFieldBegin(OUCH3_FIELD_DESC);
          struct.ouch3.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class testTableClassLoad_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public testTableClassLoad_resultTupleScheme getScheme() {
        return new testTableClassLoad_resultTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetOuch1()) {
          optionals.set(1);
        }
        if (struct.isSetOuch2()) {
          optionals.set(2);
        }
        if (struct.isSetOuch3()) {
          optionals.set(3);
        }
        oprot.writeBitSet(optionals, 4);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
        if (struct.isSetOuch1()) {
          struct.ouch1.write(oprot);
        }
        if (struct.isSetOuch2()) {
          struct.ouch2.write(oprot);
        }
        if (struct.isSetOuch3()) {
          struct.ouch3.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, testTableClassLoad_result struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.ouch1 = new AccumuloException();
          struct.ouch1.read(iprot);
          struct.setOuch1IsSet(true);
        }
        if (incoming.get(2)) {
          struct.ouch2 = new AccumuloSecurityException();
          struct.ouch2.read(iprot);
          struct.setOuch2IsSet(true);
        }
        if (incoming.get(3)) {
          struct.ouch3 = new TableNotFoundException();
          struct.ouch3.read(iprot);
          struct.setOuch3IsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("pingTabletServer_args");

    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField TSERVER_FIELD_DESC = new org.apache.thrift.protocol.TField("tserver", org.apache.thrift.protocol.TType.STRING, (short)2);

    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 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 java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // LOGIN
            return LOGIN;
          case 2: // TSERVER
            return TSERVER;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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 = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(pingTabletServer_args.class, metaDataMap);
    }

    public pingTabletServer_args() {
    }

    public pingTabletServer_args(
      java.nio.ByteBuffer login,
      java.lang.String tserver)
    {
      this();
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      this.tserver = tserver;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public pingTabletServer_args(pingTabletServer_args other) {
      if (other.isSetLogin()) {
        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
      }
      if (other.isSetTserver()) {
        this.tserver = other.tserver;
      }
    }

    public pingTabletServer_args deepCopy() {
      return new pingTabletServer_args(this);
    }

    @Override
    public void clear() {
      this.login = null;
      this.tserver = null;
    }

    public byte[] getLogin() {
      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
      return login == null ? null : login.array();
    }

    public java.nio.ByteBuffer bufferForLogin() {
      return org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    public pingTabletServer_args setLogin(byte[] login) {
      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
      return this;
    }

    public pingTabletServer_args setLogin(java.nio.ByteBuffer login) {
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      return this;
    }

    public void unsetLogin() {
      this.login = null;
    }

    /** Returns true if field login is set (has been assigned a value) and false otherwise */
    public boolean isSetLogin() {
      return this.login != null;
    }

    public void setLoginIsSet(boolean value) {
      if (!value) {
        this.login = null;
      }
    }

    public java.lang.String getTserver() {
      return this.tserver;
    }

    public pingTabletServer_args setTserver(java.lang.String tserver) {
      this.tserver = tserver;
      return this;
    }

    public void unsetTserver() {
      this.tserver = null;
    }

    /** Returns true if field tserver is set (has been assigned a value) and false otherwise */
    public boolean isSetTserver() {
      return this.tserver != null;
    }

    public void setTserverIsSet(boolean value) {
      if (!value) {
        this.tserver = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case LOGIN:
        if (value == null) {
          unsetLogin();
        } else {
          if (value instanceof byte[]) {
            setLogin((byte[])value);
          } else {
            setLogin((java.nio.ByteBuffer)value);
          }
        }
        break;

      case TSERVER:
        if (value == null) {
          unsetTserver();
        } else {
          setTserver((java.lang.String)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case LOGIN:
        return getLogin();

      case TSERVER:
        return getTserver();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case LOGIN:
        return isSetLogin();
      case TSERVER:
        return isSetTserver();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof pingTabletServer_args)
        return this.equals((pingTabletServer_args)that);
      return false;
    }

    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();
      if (this_present_login || that_present_login) {
        if (!(this_present_login && that_present_login))
          return false;
        if (!this.login.equals(that.login))
          return false;
      }

      boolean this_present_tserver = true && this.isSetTserver();
      boolean that_present_tserver = true && that.isSetTserver();
      if (this_present_tserver || that_present_tserver) {
        if (!(this_present_tserver && that_present_tserver))
          return false;
        if (!this.tserver.equals(that.tserver))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
      if (isSetLogin())
        hashCode = hashCode * 8191 + login.hashCode();

      hashCode = hashCode * 8191 + ((isSetTserver()) ? 131071 : 524287);
      if (isSetTserver())
        hashCode = hashCode * 8191 + tserver.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(pingTabletServer_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLogin()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetTserver()).compareTo(other.isSetTserver());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetTserver()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.tserver, other.tserver);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("pingTabletServer_args(");
      boolean first = true;

      sb.append("login:");
      if (this.login == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.login, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("tserver:");
      if (this.tserver == null) {
        sb.append("null");
      } else {
        sb.append(this.tserver);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class pingTabletServer_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public pingTabletServer_argsStandardScheme getScheme() {
        return new pingTabletServer_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // LOGIN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.login = iprot.readBinary();
                struct.setLoginIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // TSERVER
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.tserver = iprot.readString();
                struct.setTserverIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, pingTabletServer_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.login != null) {
          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
          oprot.writeBinary(struct.login);
          oprot.writeFieldEnd();
        }
        if (struct.tserver != null) {
          oprot.writeFieldBegin(TSERVER_FIELD_DESC);
          oprot.writeString(struct.tserver);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    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 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 {
        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);
        }
        if (struct.isSetTserver()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetLogin()) {
          oprot.writeBinary(struct.login);
        }
        if (struct.isSetTserver()) {
          oprot.writeString(struct.tserver);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, pingTabletServer_args struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.tserver = iprot.readString();
          struct.setTserverIsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("pingTabletServer_result");

    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);

    private static final org.apache.thrift.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

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      OUCH1((short)1, "ouch1"),
      OUCH2((short)2, "ouch2");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // OUCH1
            return OUCH1;
          case 2: // OUCH2
            return OUCH2;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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.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);
    }

    public pingTabletServer_result() {
    }

    public pingTabletServer_result(
      AccumuloException ouch1,
      AccumuloSecurityException ouch2)
    {
      this();
      this.ouch1 = ouch1;
      this.ouch2 = ouch2;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public pingTabletServer_result(pingTabletServer_result other) {
      if (other.isSetOuch1()) {
        this.ouch1 = new AccumuloException(other.ouch1);
      }
      if (other.isSetOuch2()) {
        this.ouch2 = new AccumuloSecurityException(other.ouch2);
      }
    }

    public pingTabletServer_result deepCopy() {
      return new pingTabletServer_result(this);
    }

    @Override
    public void clear() {
      this.ouch1 = null;
      this.ouch2 = null;
    }

    public AccumuloException getOuch1() {
      return this.ouch1;
    }

    public pingTabletServer_result setOuch1(AccumuloException ouch1) {
      this.ouch1 = ouch1;
      return this;
    }

    public void unsetOuch1() {
      this.ouch1 = null;
    }

    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch1() {
      return this.ouch1 != null;
    }

    public void setOuch1IsSet(boolean value) {
      if (!value) {
        this.ouch1 = null;
      }
    }

    public AccumuloSecurityException getOuch2() {
      return this.ouch2;
    }

    public pingTabletServer_result setOuch2(AccumuloSecurityException ouch2) {
      this.ouch2 = ouch2;
      return this;
    }

    public void unsetOuch2() {
      this.ouch2 = null;
    }

    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch2() {
      return this.ouch2 != null;
    }

    public void setOuch2IsSet(boolean value) {
      if (!value) {
        this.ouch2 = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case OUCH1:
        if (value == null) {
          unsetOuch1();
        } else {
          setOuch1((AccumuloException)value);
        }
        break;

      case OUCH2:
        if (value == null) {
          unsetOuch2();
        } else {
          setOuch2((AccumuloSecurityException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case OUCH1:
        return getOuch1();

      case OUCH2:
        return getOuch2();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case OUCH1:
        return isSetOuch1();
      case OUCH2:
        return isSetOuch2();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof pingTabletServer_result)
        return this.equals((pingTabletServer_result)that);
      return false;
    }

    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();
      if (this_present_ouch1 || that_present_ouch1) {
        if (!(this_present_ouch1 && that_present_ouch1))
          return false;
        if (!this.ouch1.equals(that.ouch1))
          return false;
      }

      boolean this_present_ouch2 = true && this.isSetOuch2();
      boolean that_present_ouch2 = true && that.isSetOuch2();
      if (this_present_ouch2 || that_present_ouch2) {
        if (!(this_present_ouch2 && that_present_ouch2))
          return false;
        if (!this.ouch2.equals(that.ouch2))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
      if (isSetOuch1())
        hashCode = hashCode * 8191 + ouch1.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
      if (isSetOuch2())
        hashCode = hashCode * 8191 + ouch2.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(pingTabletServer_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch1()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch2()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("pingTabletServer_result(");
      boolean first = true;

      sb.append("ouch1:");
      if (this.ouch1 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch1);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch2:");
      if (this.ouch2 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch2);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class pingTabletServer_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public pingTabletServer_resultStandardScheme getScheme() {
        return new pingTabletServer_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // OUCH1
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch1 = new AccumuloException();
                struct.ouch1.read(iprot);
                struct.setOuch1IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OUCH2
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch2 = new AccumuloSecurityException();
                struct.ouch2.read(iprot);
                struct.setOuch2IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, pingTabletServer_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.ouch1 != null) {
          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
          struct.ouch1.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch2 != null) {
          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
          struct.ouch2.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class pingTabletServer_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public pingTabletServer_resultTupleScheme getScheme() {
        return new pingTabletServer_resultTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetOuch2()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetOuch1()) {
          struct.ouch1.write(oprot);
        }
        if (struct.isSetOuch2()) {
          struct.ouch2.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, pingTabletServer_result struct) throws org.apache.thrift.TException {
        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);
          struct.setOuch1IsSet(true);
        }
        if (incoming.get(1)) {
          struct.ouch2 = new AccumuloSecurityException();
          struct.ouch2.read(iprot);
          struct.setOuch2IsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getActiveScans_args");

    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField TSERVER_FIELD_DESC = new org.apache.thrift.protocol.TField("tserver", org.apache.thrift.protocol.TType.STRING, (short)2);

    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 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 java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // LOGIN
            return LOGIN;
          case 2: // TSERVER
            return TSERVER;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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 = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getActiveScans_args.class, metaDataMap);
    }

    public getActiveScans_args() {
    }

    public getActiveScans_args(
      java.nio.ByteBuffer login,
      java.lang.String tserver)
    {
      this();
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      this.tserver = tserver;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getActiveScans_args(getActiveScans_args other) {
      if (other.isSetLogin()) {
        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
      }
      if (other.isSetTserver()) {
        this.tserver = other.tserver;
      }
    }

    public getActiveScans_args deepCopy() {
      return new getActiveScans_args(this);
    }

    @Override
    public void clear() {
      this.login = null;
      this.tserver = null;
    }

    public byte[] getLogin() {
      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
      return login == null ? null : login.array();
    }

    public java.nio.ByteBuffer bufferForLogin() {
      return org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    public getActiveScans_args setLogin(byte[] login) {
      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
      return this;
    }

    public getActiveScans_args setLogin(java.nio.ByteBuffer login) {
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      return this;
    }

    public void unsetLogin() {
      this.login = null;
    }

    /** Returns true if field login is set (has been assigned a value) and false otherwise */
    public boolean isSetLogin() {
      return this.login != null;
    }

    public void setLoginIsSet(boolean value) {
      if (!value) {
        this.login = null;
      }
    }

    public java.lang.String getTserver() {
      return this.tserver;
    }

    public getActiveScans_args setTserver(java.lang.String tserver) {
      this.tserver = tserver;
      return this;
    }

    public void unsetTserver() {
      this.tserver = null;
    }

    /** Returns true if field tserver is set (has been assigned a value) and false otherwise */
    public boolean isSetTserver() {
      return this.tserver != null;
    }

    public void setTserverIsSet(boolean value) {
      if (!value) {
        this.tserver = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case LOGIN:
        if (value == null) {
          unsetLogin();
        } else {
          if (value instanceof byte[]) {
            setLogin((byte[])value);
          } else {
            setLogin((java.nio.ByteBuffer)value);
          }
        }
        break;

      case TSERVER:
        if (value == null) {
          unsetTserver();
        } else {
          setTserver((java.lang.String)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case LOGIN:
        return getLogin();

      case TSERVER:
        return getTserver();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case LOGIN:
        return isSetLogin();
      case TSERVER:
        return isSetTserver();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof getActiveScans_args)
        return this.equals((getActiveScans_args)that);
      return false;
    }

    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();
      if (this_present_login || that_present_login) {
        if (!(this_present_login && that_present_login))
          return false;
        if (!this.login.equals(that.login))
          return false;
      }

      boolean this_present_tserver = true && this.isSetTserver();
      boolean that_present_tserver = true && that.isSetTserver();
      if (this_present_tserver || that_present_tserver) {
        if (!(this_present_tserver && that_present_tserver))
          return false;
        if (!this.tserver.equals(that.tserver))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
      if (isSetLogin())
        hashCode = hashCode * 8191 + login.hashCode();

      hashCode = hashCode * 8191 + ((isSetTserver()) ? 131071 : 524287);
      if (isSetTserver())
        hashCode = hashCode * 8191 + tserver.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(getActiveScans_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLogin()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetTserver()).compareTo(other.isSetTserver());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetTserver()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.tserver, other.tserver);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("getActiveScans_args(");
      boolean first = true;

      sb.append("login:");
      if (this.login == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.login, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("tserver:");
      if (this.tserver == null) {
        sb.append("null");
      } else {
        sb.append(this.tserver);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class getActiveScans_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getActiveScans_argsStandardScheme getScheme() {
        return new getActiveScans_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // LOGIN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.login = iprot.readBinary();
                struct.setLoginIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // TSERVER
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.tserver = iprot.readString();
                struct.setTserverIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getActiveScans_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.login != null) {
          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
          oprot.writeBinary(struct.login);
          oprot.writeFieldEnd();
        }
        if (struct.tserver != null) {
          oprot.writeFieldBegin(TSERVER_FIELD_DESC);
          oprot.writeString(struct.tserver);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    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 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 {
        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);
        }
        if (struct.isSetTserver()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetLogin()) {
          oprot.writeBinary(struct.login);
        }
        if (struct.isSetTserver()) {
          oprot.writeString(struct.tserver);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getActiveScans_args struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.tserver = iprot.readString();
          struct.setTserverIsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getActiveScans_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.LIST, (short)0);
    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);

    private static final 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 java.util.List<ActiveScan> success; // required
    public AccumuloException ouch1; // required
    public AccumuloSecurityException ouch2; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      OUCH1((short)1, "ouch1"),
      OUCH2((short)2, "ouch2");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // OUCH1
            return OUCH1;
          case 2: // OUCH2
            return OUCH2;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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.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);
    }

    public getActiveScans_result() {
    }

    public getActiveScans_result(
      java.util.List<ActiveScan> success,
      AccumuloException ouch1,
      AccumuloSecurityException ouch2)
    {
      this();
      this.success = success;
      this.ouch1 = ouch1;
      this.ouch2 = ouch2;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getActiveScans_result(getActiveScans_result other) {
      if (other.isSetSuccess()) {
        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));
        }
        this.success = __this__success;
      }
      if (other.isSetOuch1()) {
        this.ouch1 = new AccumuloException(other.ouch1);
      }
      if (other.isSetOuch2()) {
        this.ouch2 = new AccumuloSecurityException(other.ouch2);
      }
    }

    public getActiveScans_result deepCopy() {
      return new getActiveScans_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ouch1 = null;
      this.ouch2 = null;
    }

    public int getSuccessSize() {
      return (this.success == null) ? 0 : this.success.size();
    }

    public java.util.Iterator<ActiveScan> getSuccessIterator() {
      return (this.success == null) ? null : this.success.iterator();
    }

    public void addToSuccess(ActiveScan elem) {
      if (this.success == null) {
        this.success = new java.util.ArrayList<ActiveScan>();
      }
      this.success.add(elem);
    }

    public java.util.List<ActiveScan> getSuccess() {
      return this.success;
    }

    public getActiveScans_result setSuccess(java.util.List<ActiveScan> success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return this.success != null;
    }

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public AccumuloException getOuch1() {
      return this.ouch1;
    }

    public getActiveScans_result setOuch1(AccumuloException ouch1) {
      this.ouch1 = ouch1;
      return this;
    }

    public void unsetOuch1() {
      this.ouch1 = null;
    }

    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch1() {
      return this.ouch1 != null;
    }

    public void setOuch1IsSet(boolean value) {
      if (!value) {
        this.ouch1 = null;
      }
    }

    public AccumuloSecurityException getOuch2() {
      return this.ouch2;
    }

    public getActiveScans_result setOuch2(AccumuloSecurityException ouch2) {
      this.ouch2 = ouch2;
      return this;
    }

    public void unsetOuch2() {
      this.ouch2 = null;
    }

    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch2() {
      return this.ouch2 != null;
    }

    public void setOuch2IsSet(boolean value) {
      if (!value) {
        this.ouch2 = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.util.List<ActiveScan>)value);
        }
        break;

      case OUCH1:
        if (value == null) {
          unsetOuch1();
        } else {
          setOuch1((AccumuloException)value);
        }
        break;

      case OUCH2:
        if (value == null) {
          unsetOuch2();
        } else {
          setOuch2((AccumuloSecurityException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case OUCH1:
        return getOuch1();

      case OUCH2:
        return getOuch2();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case OUCH1:
        return isSetOuch1();
      case OUCH2:
        return isSetOuch2();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof getActiveScans_result)
        return this.equals((getActiveScans_result)that);
      return false;
    }

    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();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ouch1 = true && this.isSetOuch1();
      boolean that_present_ouch1 = true && that.isSetOuch1();
      if (this_present_ouch1 || that_present_ouch1) {
        if (!(this_present_ouch1 && that_present_ouch1))
          return false;
        if (!this.ouch1.equals(that.ouch1))
          return false;
      }

      boolean this_present_ouch2 = true && this.isSetOuch2();
      boolean that_present_ouch2 = true && that.isSetOuch2();
      if (this_present_ouch2 || that_present_ouch2) {
        if (!(this_present_ouch2 && that_present_ouch2))
          return false;
        if (!this.ouch2.equals(that.ouch2))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
      if (isSetSuccess())
        hashCode = hashCode * 8191 + success.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
      if (isSetOuch1())
        hashCode = hashCode * 8191 + ouch1.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
      if (isSetOuch2())
        hashCode = hashCode * 8191 + ouch2.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(getActiveScans_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch1()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch2()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("getActiveScans_result(");
      boolean first = true;

      sb.append("success:");
      if (this.success == null) {
        sb.append("null");
      } else {
        sb.append(this.success);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch1:");
      if (this.ouch1 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch1);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch2:");
      if (this.ouch2 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch2);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class getActiveScans_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getActiveScans_resultStandardScheme getScheme() {
        return new getActiveScans_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
                {
                  org.apache.thrift.protocol.TList _list364 = iprot.readListBegin();
                  struct.success = new java.util.ArrayList<ActiveScan>(_list364.size);
                  ActiveScan _elem365;
                  for (int _i366 = 0; _i366 < _list364.size; ++_i366)
                  {
                    _elem365 = new ActiveScan();
                    _elem365.read(iprot);
                    struct.success.add(_elem365);
                  }
                  iprot.readListEnd();
                }
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // OUCH1
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch1 = new AccumuloException();
                struct.ouch1.read(iprot);
                struct.setOuch1IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OUCH2
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch2 = new AccumuloSecurityException();
                struct.ouch2.read(iprot);
                struct.setOuch2IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getActiveScans_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, struct.success.size()));
            for (ActiveScan _iter367 : struct.success)
            {
              _iter367.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.ouch1 != null) {
          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
          struct.ouch1.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch2 != null) {
          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
          struct.ouch2.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getActiveScans_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getActiveScans_resultTupleScheme getScheme() {
        return new getActiveScans_resultTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetOuch1()) {
          optionals.set(1);
        }
        if (struct.isSetOuch2()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetSuccess()) {
          {
            oprot.writeI32(struct.success.size());
            for (ActiveScan _iter368 : struct.success)
            {
              _iter368.write(oprot);
            }
          }
        }
        if (struct.isSetOuch1()) {
          struct.ouch1.write(oprot);
        }
        if (struct.isSetOuch2()) {
          struct.ouch2.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getActiveScans_result struct) throws org.apache.thrift.TException {
        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 java.util.ArrayList<ActiveScan>(_list369.size);
            ActiveScan _elem370;
            for (int _i371 = 0; _i371 < _list369.size; ++_i371)
            {
              _elem370 = new ActiveScan();
              _elem370.read(iprot);
              struct.success.add(_elem370);
            }
          }
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ouch1 = new AccumuloException();
          struct.ouch1.read(iprot);
          struct.setOuch1IsSet(true);
        }
        if (incoming.get(2)) {
          struct.ouch2 = new AccumuloSecurityException();
          struct.ouch2.read(iprot);
          struct.setOuch2IsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getActiveCompactions_args");

    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField TSERVER_FIELD_DESC = new org.apache.thrift.protocol.TField("tserver", org.apache.thrift.protocol.TType.STRING, (short)2);

    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 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 java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // LOGIN
            return LOGIN;
          case 2: // TSERVER
            return TSERVER;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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 = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getActiveCompactions_args.class, metaDataMap);
    }

    public getActiveCompactions_args() {
    }

    public getActiveCompactions_args(
      java.nio.ByteBuffer login,
      java.lang.String tserver)
    {
      this();
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      this.tserver = tserver;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getActiveCompactions_args(getActiveCompactions_args other) {
      if (other.isSetLogin()) {
        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
      }
      if (other.isSetTserver()) {
        this.tserver = other.tserver;
      }
    }

    public getActiveCompactions_args deepCopy() {
      return new getActiveCompactions_args(this);
    }

    @Override
    public void clear() {
      this.login = null;
      this.tserver = null;
    }

    public byte[] getLogin() {
      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
      return login == null ? null : login.array();
    }

    public java.nio.ByteBuffer bufferForLogin() {
      return org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    public getActiveCompactions_args setLogin(byte[] login) {
      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
      return this;
    }

    public getActiveCompactions_args setLogin(java.nio.ByteBuffer login) {
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      return this;
    }

    public void unsetLogin() {
      this.login = null;
    }

    /** Returns true if field login is set (has been assigned a value) and false otherwise */
    public boolean isSetLogin() {
      return this.login != null;
    }

    public void setLoginIsSet(boolean value) {
      if (!value) {
        this.login = null;
      }
    }

    public java.lang.String getTserver() {
      return this.tserver;
    }

    public getActiveCompactions_args setTserver(java.lang.String tserver) {
      this.tserver = tserver;
      return this;
    }

    public void unsetTserver() {
      this.tserver = null;
    }

    /** Returns true if field tserver is set (has been assigned a value) and false otherwise */
    public boolean isSetTserver() {
      return this.tserver != null;
    }

    public void setTserverIsSet(boolean value) {
      if (!value) {
        this.tserver = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case LOGIN:
        if (value == null) {
          unsetLogin();
        } else {
          if (value instanceof byte[]) {
            setLogin((byte[])value);
          } else {
            setLogin((java.nio.ByteBuffer)value);
          }
        }
        break;

      case TSERVER:
        if (value == null) {
          unsetTserver();
        } else {
          setTserver((java.lang.String)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case LOGIN:
        return getLogin();

      case TSERVER:
        return getTserver();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case LOGIN:
        return isSetLogin();
      case TSERVER:
        return isSetTserver();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof getActiveCompactions_args)
        return this.equals((getActiveCompactions_args)that);
      return false;
    }

    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();
      if (this_present_login || that_present_login) {
        if (!(this_present_login && that_present_login))
          return false;
        if (!this.login.equals(that.login))
          return false;
      }

      boolean this_present_tserver = true && this.isSetTserver();
      boolean that_present_tserver = true && that.isSetTserver();
      if (this_present_tserver || that_present_tserver) {
        if (!(this_present_tserver && that_present_tserver))
          return false;
        if (!this.tserver.equals(that.tserver))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
      if (isSetLogin())
        hashCode = hashCode * 8191 + login.hashCode();

      hashCode = hashCode * 8191 + ((isSetTserver()) ? 131071 : 524287);
      if (isSetTserver())
        hashCode = hashCode * 8191 + tserver.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(getActiveCompactions_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLogin()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetTserver()).compareTo(other.isSetTserver());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetTserver()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.tserver, other.tserver);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("getActiveCompactions_args(");
      boolean first = true;

      sb.append("login:");
      if (this.login == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.login, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("tserver:");
      if (this.tserver == null) {
        sb.append("null");
      } else {
        sb.append(this.tserver);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class getActiveCompactions_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getActiveCompactions_argsStandardScheme getScheme() {
        return new getActiveCompactions_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // LOGIN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.login = iprot.readBinary();
                struct.setLoginIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // TSERVER
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.tserver = iprot.readString();
                struct.setTserverIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getActiveCompactions_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.login != null) {
          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
          oprot.writeBinary(struct.login);
          oprot.writeFieldEnd();
        }
        if (struct.tserver != null) {
          oprot.writeFieldBegin(TSERVER_FIELD_DESC);
          oprot.writeString(struct.tserver);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    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 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 {
        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);
        }
        if (struct.isSetTserver()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetLogin()) {
          oprot.writeBinary(struct.login);
        }
        if (struct.isSetTserver()) {
          oprot.writeString(struct.tserver);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getActiveCompactions_args struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.tserver = iprot.readString();
          struct.setTserverIsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getActiveCompactions_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.LIST, (short)0);
    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);

    private static final 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 java.util.List<ActiveCompaction> success; // required
    public AccumuloException ouch1; // required
    public AccumuloSecurityException ouch2; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      OUCH1((short)1, "ouch1"),
      OUCH2((short)2, "ouch2");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // OUCH1
            return OUCH1;
          case 2: // OUCH2
            return OUCH2;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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.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);
    }

    public getActiveCompactions_result() {
    }

    public getActiveCompactions_result(
      java.util.List<ActiveCompaction> success,
      AccumuloException ouch1,
      AccumuloSecurityException ouch2)
    {
      this();
      this.success = success;
      this.ouch1 = ouch1;
      this.ouch2 = ouch2;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getActiveCompactions_result(getActiveCompactions_result other) {
      if (other.isSetSuccess()) {
        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));
        }
        this.success = __this__success;
      }
      if (other.isSetOuch1()) {
        this.ouch1 = new AccumuloException(other.ouch1);
      }
      if (other.isSetOuch2()) {
        this.ouch2 = new AccumuloSecurityException(other.ouch2);
      }
    }

    public getActiveCompactions_result deepCopy() {
      return new getActiveCompactions_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ouch1 = null;
      this.ouch2 = null;
    }

    public int getSuccessSize() {
      return (this.success == null) ? 0 : this.success.size();
    }

    public java.util.Iterator<ActiveCompaction> getSuccessIterator() {
      return (this.success == null) ? null : this.success.iterator();
    }

    public void addToSuccess(ActiveCompaction elem) {
      if (this.success == null) {
        this.success = new java.util.ArrayList<ActiveCompaction>();
      }
      this.success.add(elem);
    }

    public java.util.List<ActiveCompaction> getSuccess() {
      return this.success;
    }

    public getActiveCompactions_result setSuccess(java.util.List<ActiveCompaction> success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return this.success != null;
    }

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public AccumuloException getOuch1() {
      return this.ouch1;
    }

    public getActiveCompactions_result setOuch1(AccumuloException ouch1) {
      this.ouch1 = ouch1;
      return this;
    }

    public void unsetOuch1() {
      this.ouch1 = null;
    }

    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch1() {
      return this.ouch1 != null;
    }

    public void setOuch1IsSet(boolean value) {
      if (!value) {
        this.ouch1 = null;
      }
    }

    public AccumuloSecurityException getOuch2() {
      return this.ouch2;
    }

    public getActiveCompactions_result setOuch2(AccumuloSecurityException ouch2) {
      this.ouch2 = ouch2;
      return this;
    }

    public void unsetOuch2() {
      this.ouch2 = null;
    }

    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch2() {
      return this.ouch2 != null;
    }

    public void setOuch2IsSet(boolean value) {
      if (!value) {
        this.ouch2 = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.util.List<ActiveCompaction>)value);
        }
        break;

      case OUCH1:
        if (value == null) {
          unsetOuch1();
        } else {
          setOuch1((AccumuloException)value);
        }
        break;

      case OUCH2:
        if (value == null) {
          unsetOuch2();
        } else {
          setOuch2((AccumuloSecurityException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case OUCH1:
        return getOuch1();

      case OUCH2:
        return getOuch2();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case OUCH1:
        return isSetOuch1();
      case OUCH2:
        return isSetOuch2();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof getActiveCompactions_result)
        return this.equals((getActiveCompactions_result)that);
      return false;
    }

    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();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ouch1 = true && this.isSetOuch1();
      boolean that_present_ouch1 = true && that.isSetOuch1();
      if (this_present_ouch1 || that_present_ouch1) {
        if (!(this_present_ouch1 && that_present_ouch1))
          return false;
        if (!this.ouch1.equals(that.ouch1))
          return false;
      }

      boolean this_present_ouch2 = true && this.isSetOuch2();
      boolean that_present_ouch2 = true && that.isSetOuch2();
      if (this_present_ouch2 || that_present_ouch2) {
        if (!(this_present_ouch2 && that_present_ouch2))
          return false;
        if (!this.ouch2.equals(that.ouch2))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
      if (isSetSuccess())
        hashCode = hashCode * 8191 + success.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
      if (isSetOuch1())
        hashCode = hashCode * 8191 + ouch1.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
      if (isSetOuch2())
        hashCode = hashCode * 8191 + ouch2.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(getActiveCompactions_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch1()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch2()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("getActiveCompactions_result(");
      boolean first = true;

      sb.append("success:");
      if (this.success == null) {
        sb.append("null");
      } else {
        sb.append(this.success);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch1:");
      if (this.ouch1 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch1);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch2:");
      if (this.ouch2 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch2);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class getActiveCompactions_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getActiveCompactions_resultStandardScheme getScheme() {
        return new getActiveCompactions_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
                {
                  org.apache.thrift.protocol.TList _list372 = iprot.readListBegin();
                  struct.success = new java.util.ArrayList<ActiveCompaction>(_list372.size);
                  ActiveCompaction _elem373;
                  for (int _i374 = 0; _i374 < _list372.size; ++_i374)
                  {
                    _elem373 = new ActiveCompaction();
                    _elem373.read(iprot);
                    struct.success.add(_elem373);
                  }
                  iprot.readListEnd();
                }
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // OUCH1
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch1 = new AccumuloException();
                struct.ouch1.read(iprot);
                struct.setOuch1IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OUCH2
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch2 = new AccumuloSecurityException();
                struct.ouch2.read(iprot);
                struct.setOuch2IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getActiveCompactions_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, struct.success.size()));
            for (ActiveCompaction _iter375 : struct.success)
            {
              _iter375.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.ouch1 != null) {
          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
          struct.ouch1.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch2 != null) {
          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
          struct.ouch2.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getActiveCompactions_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getActiveCompactions_resultTupleScheme getScheme() {
        return new getActiveCompactions_resultTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetOuch1()) {
          optionals.set(1);
        }
        if (struct.isSetOuch2()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetSuccess()) {
          {
            oprot.writeI32(struct.success.size());
            for (ActiveCompaction _iter376 : struct.success)
            {
              _iter376.write(oprot);
            }
          }
        }
        if (struct.isSetOuch1()) {
          struct.ouch1.write(oprot);
        }
        if (struct.isSetOuch2()) {
          struct.ouch2.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getActiveCompactions_result struct) throws org.apache.thrift.TException {
        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 java.util.ArrayList<ActiveCompaction>(_list377.size);
            ActiveCompaction _elem378;
            for (int _i379 = 0; _i379 < _list377.size; ++_i379)
            {
              _elem378 = new ActiveCompaction();
              _elem378.read(iprot);
              struct.success.add(_elem378);
            }
          }
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ouch1 = new AccumuloException();
          struct.ouch1.read(iprot);
          struct.setOuch1IsSet(true);
        }
        if (incoming.get(2)) {
          struct.ouch2 = new AccumuloSecurityException();
          struct.ouch2.read(iprot);
          struct.setOuch2IsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getSiteConfiguration_args");

    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new getSiteConfiguration_argsStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new getSiteConfiguration_argsTupleSchemeFactory();

    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 java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // LOGIN
            return LOGIN;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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 = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getSiteConfiguration_args.class, metaDataMap);
    }

    public getSiteConfiguration_args() {
    }

    public getSiteConfiguration_args(
      java.nio.ByteBuffer login)
    {
      this();
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getSiteConfiguration_args(getSiteConfiguration_args other) {
      if (other.isSetLogin()) {
        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
      }
    }

    public getSiteConfiguration_args deepCopy() {
      return new getSiteConfiguration_args(this);
    }

    @Override
    public void clear() {
      this.login = null;
    }

    public byte[] getLogin() {
      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
      return login == null ? null : login.array();
    }

    public java.nio.ByteBuffer bufferForLogin() {
      return org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    public getSiteConfiguration_args setLogin(byte[] login) {
      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
      return this;
    }

    public getSiteConfiguration_args setLogin(java.nio.ByteBuffer login) {
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      return this;
    }

    public void unsetLogin() {
      this.login = null;
    }

    /** Returns true if field login is set (has been assigned a value) and false otherwise */
    public boolean isSetLogin() {
      return this.login != null;
    }

    public void setLoginIsSet(boolean value) {
      if (!value) {
        this.login = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case LOGIN:
        if (value == null) {
          unsetLogin();
        } else {
          if (value instanceof byte[]) {
            setLogin((byte[])value);
          } else {
            setLogin((java.nio.ByteBuffer)value);
          }
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case LOGIN:
        return getLogin();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case LOGIN:
        return isSetLogin();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof getSiteConfiguration_args)
        return this.equals((getSiteConfiguration_args)that);
      return false;
    }

    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();
      if (this_present_login || that_present_login) {
        if (!(this_present_login && that_present_login))
          return false;
        if (!this.login.equals(that.login))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
      if (isSetLogin())
        hashCode = hashCode * 8191 + login.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(getSiteConfiguration_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLogin()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("getSiteConfiguration_args(");
      boolean first = true;

      sb.append("login:");
      if (this.login == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.login, sb);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class getSiteConfiguration_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getSiteConfiguration_argsStandardScheme getScheme() {
        return new getSiteConfiguration_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // LOGIN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.login = iprot.readBinary();
                struct.setLoginIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getSiteConfiguration_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.login != null) {
          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
          oprot.writeBinary(struct.login);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getSiteConfiguration_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getSiteConfiguration_argsTupleScheme getScheme() {
        return new getSiteConfiguration_argsTupleScheme();
      }
    }

    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 {
        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);
        }
        oprot.writeBitSet(optionals, 1);
        if (struct.isSetLogin()) {
          oprot.writeBinary(struct.login);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getSiteConfiguration_args struct) throws org.apache.thrift.TException {
        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);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getSiteConfiguration_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.MAP, (short)0);
    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new getSiteConfiguration_resultStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new getSiteConfiguration_resultTupleSchemeFactory();

    public java.util.Map<java.lang.String,java.lang.String> success; // required
    public AccumuloException ouch1; // required
    public AccumuloSecurityException ouch2; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      OUCH1((short)1, "ouch1"),
      OUCH2((short)2, "ouch2");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // OUCH1
            return OUCH1;
          case 2: // OUCH2
            return OUCH2;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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.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);
    }

    public getSiteConfiguration_result() {
    }

    public getSiteConfiguration_result(
      java.util.Map<java.lang.String,java.lang.String> success,
      AccumuloException ouch1,
      AccumuloSecurityException ouch2)
    {
      this();
      this.success = success;
      this.ouch1 = ouch1;
      this.ouch2 = ouch2;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getSiteConfiguration_result(getSiteConfiguration_result other) {
      if (other.isSetSuccess()) {
        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()) {
        this.ouch1 = new AccumuloException(other.ouch1);
      }
      if (other.isSetOuch2()) {
        this.ouch2 = new AccumuloSecurityException(other.ouch2);
      }
    }

    public getSiteConfiguration_result deepCopy() {
      return new getSiteConfiguration_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ouch1 = null;
      this.ouch2 = null;
    }

    public int getSuccessSize() {
      return (this.success == null) ? 0 : this.success.size();
    }

    public void putToSuccess(java.lang.String key, java.lang.String val) {
      if (this.success == null) {
        this.success = new java.util.HashMap<java.lang.String,java.lang.String>();
      }
      this.success.put(key, val);
    }

    public java.util.Map<java.lang.String,java.lang.String> getSuccess() {
      return this.success;
    }

    public getSiteConfiguration_result setSuccess(java.util.Map<java.lang.String,java.lang.String> success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return this.success != null;
    }

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public AccumuloException getOuch1() {
      return this.ouch1;
    }

    public getSiteConfiguration_result setOuch1(AccumuloException ouch1) {
      this.ouch1 = ouch1;
      return this;
    }

    public void unsetOuch1() {
      this.ouch1 = null;
    }

    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch1() {
      return this.ouch1 != null;
    }

    public void setOuch1IsSet(boolean value) {
      if (!value) {
        this.ouch1 = null;
      }
    }

    public AccumuloSecurityException getOuch2() {
      return this.ouch2;
    }

    public getSiteConfiguration_result setOuch2(AccumuloSecurityException ouch2) {
      this.ouch2 = ouch2;
      return this;
    }

    public void unsetOuch2() {
      this.ouch2 = null;
    }

    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch2() {
      return this.ouch2 != null;
    }

    public void setOuch2IsSet(boolean value) {
      if (!value) {
        this.ouch2 = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.util.Map<java.lang.String,java.lang.String>)value);
        }
        break;

      case OUCH1:
        if (value == null) {
          unsetOuch1();
        } else {
          setOuch1((AccumuloException)value);
        }
        break;

      case OUCH2:
        if (value == null) {
          unsetOuch2();
        } else {
          setOuch2((AccumuloSecurityException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case OUCH1:
        return getOuch1();

      case OUCH2:
        return getOuch2();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case OUCH1:
        return isSetOuch1();
      case OUCH2:
        return isSetOuch2();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof getSiteConfiguration_result)
        return this.equals((getSiteConfiguration_result)that);
      return false;
    }

    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();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ouch1 = true && this.isSetOuch1();
      boolean that_present_ouch1 = true && that.isSetOuch1();
      if (this_present_ouch1 || that_present_ouch1) {
        if (!(this_present_ouch1 && that_present_ouch1))
          return false;
        if (!this.ouch1.equals(that.ouch1))
          return false;
      }

      boolean this_present_ouch2 = true && this.isSetOuch2();
      boolean that_present_ouch2 = true && that.isSetOuch2();
      if (this_present_ouch2 || that_present_ouch2) {
        if (!(this_present_ouch2 && that_present_ouch2))
          return false;
        if (!this.ouch2.equals(that.ouch2))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
      if (isSetSuccess())
        hashCode = hashCode * 8191 + success.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
      if (isSetOuch1())
        hashCode = hashCode * 8191 + ouch1.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
      if (isSetOuch2())
        hashCode = hashCode * 8191 + ouch2.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(getSiteConfiguration_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch1()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch2()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("getSiteConfiguration_result(");
      boolean first = true;

      sb.append("success:");
      if (this.success == null) {
        sb.append("null");
      } else {
        sb.append(this.success);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch1:");
      if (this.ouch1 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch1);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch2:");
      if (this.ouch2 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch2);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class getSiteConfiguration_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getSiteConfiguration_resultStandardScheme getScheme() {
        return new getSiteConfiguration_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.MAP) {
                {
                  org.apache.thrift.protocol.TMap _map380 = iprot.readMapBegin();
                  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();
                    _val382 = iprot.readString();
                    struct.success.put(_key381, _val382);
                  }
                  iprot.readMapEnd();
                }
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // OUCH1
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch1 = new AccumuloException();
                struct.ouch1.read(iprot);
                struct.setOuch1IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OUCH2
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch2 = new AccumuloSecurityException();
                struct.ouch2.read(iprot);
                struct.setOuch2IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getSiteConfiguration_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          {
            oprot.writeMapBegin(new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.STRING, struct.success.size()));
            for (java.util.Map.Entry<java.lang.String, java.lang.String> _iter384 : struct.success.entrySet())
            {
              oprot.writeString(_iter384.getKey());
              oprot.writeString(_iter384.getValue());
            }
            oprot.writeMapEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.ouch1 != null) {
          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
          struct.ouch1.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch2 != null) {
          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
          struct.ouch2.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getSiteConfiguration_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getSiteConfiguration_resultTupleScheme getScheme() {
        return new getSiteConfiguration_resultTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetOuch1()) {
          optionals.set(1);
        }
        if (struct.isSetOuch2()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetSuccess()) {
          {
            oprot.writeI32(struct.success.size());
            for (java.util.Map.Entry<java.lang.String, java.lang.String> _iter385 : struct.success.entrySet())
            {
              oprot.writeString(_iter385.getKey());
              oprot.writeString(_iter385.getValue());
            }
          }
        }
        if (struct.isSetOuch1()) {
          struct.ouch1.write(oprot);
        }
        if (struct.isSetOuch2()) {
          struct.ouch2.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getSiteConfiguration_result struct) throws org.apache.thrift.TException {
        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 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();
              _val388 = iprot.readString();
              struct.success.put(_key387, _val388);
            }
          }
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ouch1 = new AccumuloException();
          struct.ouch1.read(iprot);
          struct.setOuch1IsSet(true);
        }
        if (incoming.get(2)) {
          struct.ouch2 = new AccumuloSecurityException();
          struct.ouch2.read(iprot);
          struct.setOuch2IsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getSystemConfiguration_args");

    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new getSystemConfiguration_argsStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new getSystemConfiguration_argsTupleSchemeFactory();

    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 java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // LOGIN
            return LOGIN;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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 = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getSystemConfiguration_args.class, metaDataMap);
    }

    public getSystemConfiguration_args() {
    }

    public getSystemConfiguration_args(
      java.nio.ByteBuffer login)
    {
      this();
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getSystemConfiguration_args(getSystemConfiguration_args other) {
      if (other.isSetLogin()) {
        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
      }
    }

    public getSystemConfiguration_args deepCopy() {
      return new getSystemConfiguration_args(this);
    }

    @Override
    public void clear() {
      this.login = null;
    }

    public byte[] getLogin() {
      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
      return login == null ? null : login.array();
    }

    public java.nio.ByteBuffer bufferForLogin() {
      return org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    public getSystemConfiguration_args setLogin(byte[] login) {
      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
      return this;
    }

    public getSystemConfiguration_args setLogin(java.nio.ByteBuffer login) {
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      return this;
    }

    public void unsetLogin() {
      this.login = null;
    }

    /** Returns true if field login is set (has been assigned a value) and false otherwise */
    public boolean isSetLogin() {
      return this.login != null;
    }

    public void setLoginIsSet(boolean value) {
      if (!value) {
        this.login = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case LOGIN:
        if (value == null) {
          unsetLogin();
        } else {
          if (value instanceof byte[]) {
            setLogin((byte[])value);
          } else {
            setLogin((java.nio.ByteBuffer)value);
          }
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case LOGIN:
        return getLogin();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case LOGIN:
        return isSetLogin();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof getSystemConfiguration_args)
        return this.equals((getSystemConfiguration_args)that);
      return false;
    }

    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();
      if (this_present_login || that_present_login) {
        if (!(this_present_login && that_present_login))
          return false;
        if (!this.login.equals(that.login))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
      if (isSetLogin())
        hashCode = hashCode * 8191 + login.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(getSystemConfiguration_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLogin()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("getSystemConfiguration_args(");
      boolean first = true;

      sb.append("login:");
      if (this.login == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.login, sb);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class getSystemConfiguration_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getSystemConfiguration_argsStandardScheme getScheme() {
        return new getSystemConfiguration_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // LOGIN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.login = iprot.readBinary();
                struct.setLoginIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getSystemConfiguration_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.login != null) {
          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
          oprot.writeBinary(struct.login);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getSystemConfiguration_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getSystemConfiguration_argsTupleScheme getScheme() {
        return new getSystemConfiguration_argsTupleScheme();
      }
    }

    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 {
        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);
        }
        oprot.writeBitSet(optionals, 1);
        if (struct.isSetLogin()) {
          oprot.writeBinary(struct.login);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getSystemConfiguration_args struct) throws org.apache.thrift.TException {
        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);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getSystemConfiguration_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.MAP, (short)0);
    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new getSystemConfiguration_resultStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new getSystemConfiguration_resultTupleSchemeFactory();

    public java.util.Map<java.lang.String,java.lang.String> success; // required
    public AccumuloException ouch1; // required
    public AccumuloSecurityException ouch2; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      OUCH1((short)1, "ouch1"),
      OUCH2((short)2, "ouch2");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // OUCH1
            return OUCH1;
          case 2: // OUCH2
            return OUCH2;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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.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);
    }

    public getSystemConfiguration_result() {
    }

    public getSystemConfiguration_result(
      java.util.Map<java.lang.String,java.lang.String> success,
      AccumuloException ouch1,
      AccumuloSecurityException ouch2)
    {
      this();
      this.success = success;
      this.ouch1 = ouch1;
      this.ouch2 = ouch2;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getSystemConfiguration_result(getSystemConfiguration_result other) {
      if (other.isSetSuccess()) {
        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()) {
        this.ouch1 = new AccumuloException(other.ouch1);
      }
      if (other.isSetOuch2()) {
        this.ouch2 = new AccumuloSecurityException(other.ouch2);
      }
    }

    public getSystemConfiguration_result deepCopy() {
      return new getSystemConfiguration_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ouch1 = null;
      this.ouch2 = null;
    }

    public int getSuccessSize() {
      return (this.success == null) ? 0 : this.success.size();
    }

    public void putToSuccess(java.lang.String key, java.lang.String val) {
      if (this.success == null) {
        this.success = new java.util.HashMap<java.lang.String,java.lang.String>();
      }
      this.success.put(key, val);
    }

    public java.util.Map<java.lang.String,java.lang.String> getSuccess() {
      return this.success;
    }

    public getSystemConfiguration_result setSuccess(java.util.Map<java.lang.String,java.lang.String> success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return this.success != null;
    }

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public AccumuloException getOuch1() {
      return this.ouch1;
    }

    public getSystemConfiguration_result setOuch1(AccumuloException ouch1) {
      this.ouch1 = ouch1;
      return this;
    }

    public void unsetOuch1() {
      this.ouch1 = null;
    }

    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch1() {
      return this.ouch1 != null;
    }

    public void setOuch1IsSet(boolean value) {
      if (!value) {
        this.ouch1 = null;
      }
    }

    public AccumuloSecurityException getOuch2() {
      return this.ouch2;
    }

    public getSystemConfiguration_result setOuch2(AccumuloSecurityException ouch2) {
      this.ouch2 = ouch2;
      return this;
    }

    public void unsetOuch2() {
      this.ouch2 = null;
    }

    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch2() {
      return this.ouch2 != null;
    }

    public void setOuch2IsSet(boolean value) {
      if (!value) {
        this.ouch2 = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.util.Map<java.lang.String,java.lang.String>)value);
        }
        break;

      case OUCH1:
        if (value == null) {
          unsetOuch1();
        } else {
          setOuch1((AccumuloException)value);
        }
        break;

      case OUCH2:
        if (value == null) {
          unsetOuch2();
        } else {
          setOuch2((AccumuloSecurityException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case OUCH1:
        return getOuch1();

      case OUCH2:
        return getOuch2();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case OUCH1:
        return isSetOuch1();
      case OUCH2:
        return isSetOuch2();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof getSystemConfiguration_result)
        return this.equals((getSystemConfiguration_result)that);
      return false;
    }

    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();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ouch1 = true && this.isSetOuch1();
      boolean that_present_ouch1 = true && that.isSetOuch1();
      if (this_present_ouch1 || that_present_ouch1) {
        if (!(this_present_ouch1 && that_present_ouch1))
          return false;
        if (!this.ouch1.equals(that.ouch1))
          return false;
      }

      boolean this_present_ouch2 = true && this.isSetOuch2();
      boolean that_present_ouch2 = true && that.isSetOuch2();
      if (this_present_ouch2 || that_present_ouch2) {
        if (!(this_present_ouch2 && that_present_ouch2))
          return false;
        if (!this.ouch2.equals(that.ouch2))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
      if (isSetSuccess())
        hashCode = hashCode * 8191 + success.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
      if (isSetOuch1())
        hashCode = hashCode * 8191 + ouch1.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
      if (isSetOuch2())
        hashCode = hashCode * 8191 + ouch2.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(getSystemConfiguration_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch1()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch2()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("getSystemConfiguration_result(");
      boolean first = true;

      sb.append("success:");
      if (this.success == null) {
        sb.append("null");
      } else {
        sb.append(this.success);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch1:");
      if (this.ouch1 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch1);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch2:");
      if (this.ouch2 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch2);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class getSystemConfiguration_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getSystemConfiguration_resultStandardScheme getScheme() {
        return new getSystemConfiguration_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.MAP) {
                {
                  org.apache.thrift.protocol.TMap _map390 = iprot.readMapBegin();
                  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();
                    _val392 = iprot.readString();
                    struct.success.put(_key391, _val392);
                  }
                  iprot.readMapEnd();
                }
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // OUCH1
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch1 = new AccumuloException();
                struct.ouch1.read(iprot);
                struct.setOuch1IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OUCH2
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch2 = new AccumuloSecurityException();
                struct.ouch2.read(iprot);
                struct.setOuch2IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getSystemConfiguration_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          {
            oprot.writeMapBegin(new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.STRING, struct.success.size()));
            for (java.util.Map.Entry<java.lang.String, java.lang.String> _iter394 : struct.success.entrySet())
            {
              oprot.writeString(_iter394.getKey());
              oprot.writeString(_iter394.getValue());
            }
            oprot.writeMapEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.ouch1 != null) {
          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
          struct.ouch1.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch2 != null) {
          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
          struct.ouch2.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getSystemConfiguration_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getSystemConfiguration_resultTupleScheme getScheme() {
        return new getSystemConfiguration_resultTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetOuch1()) {
          optionals.set(1);
        }
        if (struct.isSetOuch2()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetSuccess()) {
          {
            oprot.writeI32(struct.success.size());
            for (java.util.Map.Entry<java.lang.String, java.lang.String> _iter395 : struct.success.entrySet())
            {
              oprot.writeString(_iter395.getKey());
              oprot.writeString(_iter395.getValue());
            }
          }
        }
        if (struct.isSetOuch1()) {
          struct.ouch1.write(oprot);
        }
        if (struct.isSetOuch2()) {
          struct.ouch2.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getSystemConfiguration_result struct) throws org.apache.thrift.TException {
        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 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();
              _val398 = iprot.readString();
              struct.success.put(_key397, _val398);
            }
          }
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ouch1 = new AccumuloException();
          struct.ouch1.read(iprot);
          struct.setOuch1IsSet(true);
        }
        if (incoming.get(2)) {
          struct.ouch2 = new AccumuloSecurityException();
          struct.ouch2.read(iprot);
          struct.setOuch2IsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getTabletServers_args");

    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new getTabletServers_argsStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new getTabletServers_argsTupleSchemeFactory();

    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 java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // LOGIN
            return LOGIN;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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 = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getTabletServers_args.class, metaDataMap);
    }

    public getTabletServers_args() {
    }

    public getTabletServers_args(
      java.nio.ByteBuffer login)
    {
      this();
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getTabletServers_args(getTabletServers_args other) {
      if (other.isSetLogin()) {
        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
      }
    }

    public getTabletServers_args deepCopy() {
      return new getTabletServers_args(this);
    }

    @Override
    public void clear() {
      this.login = null;
    }

    public byte[] getLogin() {
      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
      return login == null ? null : login.array();
    }

    public java.nio.ByteBuffer bufferForLogin() {
      return org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    public getTabletServers_args setLogin(byte[] login) {
      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
      return this;
    }

    public getTabletServers_args setLogin(java.nio.ByteBuffer login) {
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      return this;
    }

    public void unsetLogin() {
      this.login = null;
    }

    /** Returns true if field login is set (has been assigned a value) and false otherwise */
    public boolean isSetLogin() {
      return this.login != null;
    }

    public void setLoginIsSet(boolean value) {
      if (!value) {
        this.login = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case LOGIN:
        if (value == null) {
          unsetLogin();
        } else {
          if (value instanceof byte[]) {
            setLogin((byte[])value);
          } else {
            setLogin((java.nio.ByteBuffer)value);
          }
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case LOGIN:
        return getLogin();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case LOGIN:
        return isSetLogin();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof getTabletServers_args)
        return this.equals((getTabletServers_args)that);
      return false;
    }

    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();
      if (this_present_login || that_present_login) {
        if (!(this_present_login && that_present_login))
          return false;
        if (!this.login.equals(that.login))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
      if (isSetLogin())
        hashCode = hashCode * 8191 + login.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(getTabletServers_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLogin()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("getTabletServers_args(");
      boolean first = true;

      sb.append("login:");
      if (this.login == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.login, sb);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class getTabletServers_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getTabletServers_argsStandardScheme getScheme() {
        return new getTabletServers_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // LOGIN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.login = iprot.readBinary();
                struct.setLoginIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getTabletServers_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.login != null) {
          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
          oprot.writeBinary(struct.login);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getTabletServers_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getTabletServers_argsTupleScheme getScheme() {
        return new getTabletServers_argsTupleScheme();
      }
    }

    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 {
        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);
        }
        oprot.writeBitSet(optionals, 1);
        if (struct.isSetLogin()) {
          oprot.writeBinary(struct.login);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getTabletServers_args struct) throws org.apache.thrift.TException {
        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);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getTabletServers_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.LIST, (short)0);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new getTabletServers_resultStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new getTabletServers_resultTupleSchemeFactory();

    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 java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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 = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getTabletServers_result.class, metaDataMap);
    }

    public getTabletServers_result() {
    }

    public getTabletServers_result(
      java.util.List<java.lang.String> success)
    {
      this();
      this.success = success;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getTabletServers_result(getTabletServers_result other) {
      if (other.isSetSuccess()) {
        java.util.List<java.lang.String> __this__success = new java.util.ArrayList<java.lang.String>(other.success);
        this.success = __this__success;
      }
    }

    public getTabletServers_result deepCopy() {
      return new getTabletServers_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
    }

    public int getSuccessSize() {
      return (this.success == null) ? 0 : this.success.size();
    }

    public java.util.Iterator<java.lang.String> getSuccessIterator() {
      return (this.success == null) ? null : this.success.iterator();
    }

    public void addToSuccess(java.lang.String elem) {
      if (this.success == null) {
        this.success = new java.util.ArrayList<java.lang.String>();
      }
      this.success.add(elem);
    }

    public java.util.List<java.lang.String> getSuccess() {
      return this.success;
    }

    public getTabletServers_result setSuccess(java.util.List<java.lang.String> success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return this.success != null;
    }

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.util.List<java.lang.String>)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof getTabletServers_result)
        return this.equals((getTabletServers_result)that);
      return false;
    }

    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();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
      if (isSetSuccess())
        hashCode = hashCode * 8191 + success.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(getTabletServers_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("getTabletServers_result(");
      boolean first = true;

      sb.append("success:");
      if (this.success == null) {
        sb.append("null");
      } else {
        sb.append(this.success);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class getTabletServers_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getTabletServers_resultStandardScheme getScheme() {
        return new getTabletServers_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
                {
                  org.apache.thrift.protocol.TList _list400 = iprot.readListBegin();
                  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();
                    struct.success.add(_elem401);
                  }
                  iprot.readListEnd();
                }
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getTabletServers_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRING, struct.success.size()));
            for (java.lang.String _iter403 : struct.success)
            {
              oprot.writeString(_iter403);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    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 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 {
        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);
        }
        oprot.writeBitSet(optionals, 1);
        if (struct.isSetSuccess()) {
          {
            oprot.writeI32(struct.success.size());
            for (java.lang.String _iter404 : struct.success)
            {
              oprot.writeString(_iter404);
            }
          }
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getTabletServers_result struct) throws org.apache.thrift.TException {
        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 java.util.ArrayList<java.lang.String>(_list405.size);
            java.lang.String _elem406;
            for (int _i407 = 0; _i407 < _list405.size; ++_i407)
            {
              _elem406 = iprot.readString();
              struct.success.add(_elem406);
            }
          }
          struct.setSuccessIsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("removeProperty_args");

    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField PROPERTY_FIELD_DESC = new org.apache.thrift.protocol.TField("property", org.apache.thrift.protocol.TType.STRING, (short)2);

    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 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 java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // LOGIN
            return LOGIN;
          case 2: // PROPERTY
            return PROPERTY;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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 = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(removeProperty_args.class, metaDataMap);
    }

    public removeProperty_args() {
    }

    public removeProperty_args(
      java.nio.ByteBuffer login,
      java.lang.String property)
    {
      this();
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      this.property = property;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public removeProperty_args(removeProperty_args other) {
      if (other.isSetLogin()) {
        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
      }
      if (other.isSetProperty()) {
        this.property = other.property;
      }
    }

    public removeProperty_args deepCopy() {
      return new removeProperty_args(this);
    }

    @Override
    public void clear() {
      this.login = null;
      this.property = null;
    }

    public byte[] getLogin() {
      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
      return login == null ? null : login.array();
    }

    public java.nio.ByteBuffer bufferForLogin() {
      return org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    public removeProperty_args setLogin(byte[] login) {
      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
      return this;
    }

    public removeProperty_args setLogin(java.nio.ByteBuffer login) {
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      return this;
    }

    public void unsetLogin() {
      this.login = null;
    }

    /** Returns true if field login is set (has been assigned a value) and false otherwise */
    public boolean isSetLogin() {
      return this.login != null;
    }

    public void setLoginIsSet(boolean value) {
      if (!value) {
        this.login = null;
      }
    }

    public java.lang.String getProperty() {
      return this.property;
    }

    public removeProperty_args setProperty(java.lang.String property) {
      this.property = property;
      return this;
    }

    public void unsetProperty() {
      this.property = null;
    }

    /** Returns true if field property is set (has been assigned a value) and false otherwise */
    public boolean isSetProperty() {
      return this.property != null;
    }

    public void setPropertyIsSet(boolean value) {
      if (!value) {
        this.property = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case LOGIN:
        if (value == null) {
          unsetLogin();
        } else {
          if (value instanceof byte[]) {
            setLogin((byte[])value);
          } else {
            setLogin((java.nio.ByteBuffer)value);
          }
        }
        break;

      case PROPERTY:
        if (value == null) {
          unsetProperty();
        } else {
          setProperty((java.lang.String)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case LOGIN:
        return getLogin();

      case PROPERTY:
        return getProperty();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case LOGIN:
        return isSetLogin();
      case PROPERTY:
        return isSetProperty();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof removeProperty_args)
        return this.equals((removeProperty_args)that);
      return false;
    }

    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();
      if (this_present_login || that_present_login) {
        if (!(this_present_login && that_present_login))
          return false;
        if (!this.login.equals(that.login))
          return false;
      }

      boolean this_present_property = true && this.isSetProperty();
      boolean that_present_property = true && that.isSetProperty();
      if (this_present_property || that_present_property) {
        if (!(this_present_property && that_present_property))
          return false;
        if (!this.property.equals(that.property))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
      if (isSetLogin())
        hashCode = hashCode * 8191 + login.hashCode();

      hashCode = hashCode * 8191 + ((isSetProperty()) ? 131071 : 524287);
      if (isSetProperty())
        hashCode = hashCode * 8191 + property.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(removeProperty_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLogin()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetProperty()).compareTo(other.isSetProperty());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetProperty()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.property, other.property);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("removeProperty_args(");
      boolean first = true;

      sb.append("login:");
      if (this.login == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.login, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("property:");
      if (this.property == null) {
        sb.append("null");
      } else {
        sb.append(this.property);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class removeProperty_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public removeProperty_argsStandardScheme getScheme() {
        return new removeProperty_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // LOGIN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.login = iprot.readBinary();
                struct.setLoginIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // PROPERTY
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.property = iprot.readString();
                struct.setPropertyIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, removeProperty_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.login != null) {
          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
          oprot.writeBinary(struct.login);
          oprot.writeFieldEnd();
        }
        if (struct.property != null) {
          oprot.writeFieldBegin(PROPERTY_FIELD_DESC);
          oprot.writeString(struct.property);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    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 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 {
        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);
        }
        if (struct.isSetProperty()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetLogin()) {
          oprot.writeBinary(struct.login);
        }
        if (struct.isSetProperty()) {
          oprot.writeString(struct.property);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, removeProperty_args struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.property = iprot.readString();
          struct.setPropertyIsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("removeProperty_result");

    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);

    private static final org.apache.thrift.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

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      OUCH1((short)1, "ouch1"),
      OUCH2((short)2, "ouch2");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // OUCH1
            return OUCH1;
          case 2: // OUCH2
            return OUCH2;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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.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);
    }

    public removeProperty_result() {
    }

    public removeProperty_result(
      AccumuloException ouch1,
      AccumuloSecurityException ouch2)
    {
      this();
      this.ouch1 = ouch1;
      this.ouch2 = ouch2;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public removeProperty_result(removeProperty_result other) {
      if (other.isSetOuch1()) {
        this.ouch1 = new AccumuloException(other.ouch1);
      }
      if (other.isSetOuch2()) {
        this.ouch2 = new AccumuloSecurityException(other.ouch2);
      }
    }

    public removeProperty_result deepCopy() {
      return new removeProperty_result(this);
    }

    @Override
    public void clear() {
      this.ouch1 = null;
      this.ouch2 = null;
    }

    public AccumuloException getOuch1() {
      return this.ouch1;
    }

    public removeProperty_result setOuch1(AccumuloException ouch1) {
      this.ouch1 = ouch1;
      return this;
    }

    public void unsetOuch1() {
      this.ouch1 = null;
    }

    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch1() {
      return this.ouch1 != null;
    }

    public void setOuch1IsSet(boolean value) {
      if (!value) {
        this.ouch1 = null;
      }
    }

    public AccumuloSecurityException getOuch2() {
      return this.ouch2;
    }

    public removeProperty_result setOuch2(AccumuloSecurityException ouch2) {
      this.ouch2 = ouch2;
      return this;
    }

    public void unsetOuch2() {
      this.ouch2 = null;
    }

    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch2() {
      return this.ouch2 != null;
    }

    public void setOuch2IsSet(boolean value) {
      if (!value) {
        this.ouch2 = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case OUCH1:
        if (value == null) {
          unsetOuch1();
        } else {
          setOuch1((AccumuloException)value);
        }
        break;

      case OUCH2:
        if (value == null) {
          unsetOuch2();
        } else {
          setOuch2((AccumuloSecurityException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case OUCH1:
        return getOuch1();

      case OUCH2:
        return getOuch2();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case OUCH1:
        return isSetOuch1();
      case OUCH2:
        return isSetOuch2();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof removeProperty_result)
        return this.equals((removeProperty_result)that);
      return false;
    }

    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();
      if (this_present_ouch1 || that_present_ouch1) {
        if (!(this_present_ouch1 && that_present_ouch1))
          return false;
        if (!this.ouch1.equals(that.ouch1))
          return false;
      }

      boolean this_present_ouch2 = true && this.isSetOuch2();
      boolean that_present_ouch2 = true && that.isSetOuch2();
      if (this_present_ouch2 || that_present_ouch2) {
        if (!(this_present_ouch2 && that_present_ouch2))
          return false;
        if (!this.ouch2.equals(that.ouch2))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
      if (isSetOuch1())
        hashCode = hashCode * 8191 + ouch1.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
      if (isSetOuch2())
        hashCode = hashCode * 8191 + ouch2.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(removeProperty_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch1()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch2()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("removeProperty_result(");
      boolean first = true;

      sb.append("ouch1:");
      if (this.ouch1 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch1);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch2:");
      if (this.ouch2 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch2);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class removeProperty_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public removeProperty_resultStandardScheme getScheme() {
        return new removeProperty_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // OUCH1
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch1 = new AccumuloException();
                struct.ouch1.read(iprot);
                struct.setOuch1IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OUCH2
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch2 = new AccumuloSecurityException();
                struct.ouch2.read(iprot);
                struct.setOuch2IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, removeProperty_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.ouch1 != null) {
          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
          struct.ouch1.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch2 != null) {
          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
          struct.ouch2.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class removeProperty_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public removeProperty_resultTupleScheme getScheme() {
        return new removeProperty_resultTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetOuch2()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetOuch1()) {
          struct.ouch1.write(oprot);
        }
        if (struct.isSetOuch2()) {
          struct.ouch2.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, removeProperty_result struct) throws org.apache.thrift.TException {
        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);
          struct.setOuch1IsSet(true);
        }
        if (incoming.get(1)) {
          struct.ouch2 = new AccumuloSecurityException();
          struct.ouch2.read(iprot);
          struct.setOuch2IsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("setProperty_args");

    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField 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 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 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 {
      LOGIN((short)1, "login"),
      PROPERTY((short)2, "property"),
      VALUE((short)3, "value");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // LOGIN
            return LOGIN;
          case 2: // PROPERTY
            return PROPERTY;
          case 3: // VALUE
            return VALUE;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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 = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(setProperty_args.class, metaDataMap);
    }

    public setProperty_args() {
    }

    public setProperty_args(
      java.nio.ByteBuffer login,
      java.lang.String property,
      java.lang.String value)
    {
      this();
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      this.property = property;
      this.value = value;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public setProperty_args(setProperty_args other) {
      if (other.isSetLogin()) {
        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
      }
      if (other.isSetProperty()) {
        this.property = other.property;
      }
      if (other.isSetValue()) {
        this.value = other.value;
      }
    }

    public setProperty_args deepCopy() {
      return new setProperty_args(this);
    }

    @Override
    public void clear() {
      this.login = null;
      this.property = null;
      this.value = null;
    }

    public byte[] getLogin() {
      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
      return login == null ? null : login.array();
    }

    public java.nio.ByteBuffer bufferForLogin() {
      return org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    public setProperty_args setLogin(byte[] login) {
      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
      return this;
    }

    public setProperty_args setLogin(java.nio.ByteBuffer login) {
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      return this;
    }

    public void unsetLogin() {
      this.login = null;
    }

    /** Returns true if field login is set (has been assigned a value) and false otherwise */
    public boolean isSetLogin() {
      return this.login != null;
    }

    public void setLoginIsSet(boolean value) {
      if (!value) {
        this.login = null;
      }
    }

    public java.lang.String getProperty() {
      return this.property;
    }

    public setProperty_args setProperty(java.lang.String property) {
      this.property = property;
      return this;
    }

    public void unsetProperty() {
      this.property = null;
    }

    /** Returns true if field property is set (has been assigned a value) and false otherwise */
    public boolean isSetProperty() {
      return this.property != null;
    }

    public void setPropertyIsSet(boolean value) {
      if (!value) {
        this.property = null;
      }
    }

    public java.lang.String getValue() {
      return this.value;
    }

    public setProperty_args setValue(java.lang.String value) {
      this.value = value;
      return this;
    }

    public void unsetValue() {
      this.value = null;
    }

    /** Returns true if field value is set (has been assigned a value) and false otherwise */
    public boolean isSetValue() {
      return this.value != null;
    }

    public void setValueIsSet(boolean value) {
      if (!value) {
        this.value = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case LOGIN:
        if (value == null) {
          unsetLogin();
        } else {
          if (value instanceof byte[]) {
            setLogin((byte[])value);
          } else {
            setLogin((java.nio.ByteBuffer)value);
          }
        }
        break;

      case PROPERTY:
        if (value == null) {
          unsetProperty();
        } else {
          setProperty((java.lang.String)value);
        }
        break;

      case VALUE:
        if (value == null) {
          unsetValue();
        } else {
          setValue((java.lang.String)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case LOGIN:
        return getLogin();

      case PROPERTY:
        return getProperty();

      case VALUE:
        return getValue();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case LOGIN:
        return isSetLogin();
      case PROPERTY:
        return isSetProperty();
      case VALUE:
        return isSetValue();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof setProperty_args)
        return this.equals((setProperty_args)that);
      return false;
    }

    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();
      if (this_present_login || that_present_login) {
        if (!(this_present_login && that_present_login))
          return false;
        if (!this.login.equals(that.login))
          return false;
      }

      boolean this_present_property = true && this.isSetProperty();
      boolean that_present_property = true && that.isSetProperty();
      if (this_present_property || that_present_property) {
        if (!(this_present_property && that_present_property))
          return false;
        if (!this.property.equals(that.property))
          return false;
      }

      boolean this_present_value = true && this.isSetValue();
      boolean that_present_value = true && that.isSetValue();
      if (this_present_value || that_present_value) {
        if (!(this_present_value && that_present_value))
          return false;
        if (!this.value.equals(that.value))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
      if (isSetLogin())
        hashCode = hashCode * 8191 + login.hashCode();

      hashCode = hashCode * 8191 + ((isSetProperty()) ? 131071 : 524287);
      if (isSetProperty())
        hashCode = hashCode * 8191 + property.hashCode();

      hashCode = hashCode * 8191 + ((isSetValue()) ? 131071 : 524287);
      if (isSetValue())
        hashCode = hashCode * 8191 + value.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(setProperty_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLogin()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetProperty()).compareTo(other.isSetProperty());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetProperty()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.property, other.property);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetValue()).compareTo(other.isSetValue());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetValue()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.value, other.value);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("setProperty_args(");
      boolean first = true;

      sb.append("login:");
      if (this.login == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.login, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("property:");
      if (this.property == null) {
        sb.append("null");
      } else {
        sb.append(this.property);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("value:");
      if (this.value == null) {
        sb.append("null");
      } else {
        sb.append(this.value);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class setProperty_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public setProperty_argsStandardScheme getScheme() {
        return new setProperty_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // LOGIN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.login = iprot.readBinary();
                struct.setLoginIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // PROPERTY
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.property = iprot.readString();
                struct.setPropertyIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // VALUE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.value = iprot.readString();
                struct.setValueIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, setProperty_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.login != null) {
          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
          oprot.writeBinary(struct.login);
          oprot.writeFieldEnd();
        }
        if (struct.property != null) {
          oprot.writeFieldBegin(PROPERTY_FIELD_DESC);
          oprot.writeString(struct.property);
          oprot.writeFieldEnd();
        }
        if (struct.value != null) {
          oprot.writeFieldBegin(VALUE_FIELD_DESC);
          oprot.writeString(struct.value);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class setProperty_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public setProperty_argsTupleScheme getScheme() {
        return new setProperty_argsTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetProperty()) {
          optionals.set(1);
        }
        if (struct.isSetValue()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetLogin()) {
          oprot.writeBinary(struct.login);
        }
        if (struct.isSetProperty()) {
          oprot.writeString(struct.property);
        }
        if (struct.isSetValue()) {
          oprot.writeString(struct.value);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, setProperty_args struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.property = iprot.readString();
          struct.setPropertyIsSet(true);
        }
        if (incoming.get(2)) {
          struct.value = iprot.readString();
          struct.setValueIsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("setProperty_result");

    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);

    private static final org.apache.thrift.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

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      OUCH1((short)1, "ouch1"),
      OUCH2((short)2, "ouch2");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // OUCH1
            return OUCH1;
          case 2: // OUCH2
            return OUCH2;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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.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);
    }

    public setProperty_result() {
    }

    public setProperty_result(
      AccumuloException ouch1,
      AccumuloSecurityException ouch2)
    {
      this();
      this.ouch1 = ouch1;
      this.ouch2 = ouch2;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public setProperty_result(setProperty_result other) {
      if (other.isSetOuch1()) {
        this.ouch1 = new AccumuloException(other.ouch1);
      }
      if (other.isSetOuch2()) {
        this.ouch2 = new AccumuloSecurityException(other.ouch2);
      }
    }

    public setProperty_result deepCopy() {
      return new setProperty_result(this);
    }

    @Override
    public void clear() {
      this.ouch1 = null;
      this.ouch2 = null;
    }

    public AccumuloException getOuch1() {
      return this.ouch1;
    }

    public setProperty_result setOuch1(AccumuloException ouch1) {
      this.ouch1 = ouch1;
      return this;
    }

    public void unsetOuch1() {
      this.ouch1 = null;
    }

    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch1() {
      return this.ouch1 != null;
    }

    public void setOuch1IsSet(boolean value) {
      if (!value) {
        this.ouch1 = null;
      }
    }

    public AccumuloSecurityException getOuch2() {
      return this.ouch2;
    }

    public setProperty_result setOuch2(AccumuloSecurityException ouch2) {
      this.ouch2 = ouch2;
      return this;
    }

    public void unsetOuch2() {
      this.ouch2 = null;
    }

    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch2() {
      return this.ouch2 != null;
    }

    public void setOuch2IsSet(boolean value) {
      if (!value) {
        this.ouch2 = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case OUCH1:
        if (value == null) {
          unsetOuch1();
        } else {
          setOuch1((AccumuloException)value);
        }
        break;

      case OUCH2:
        if (value == null) {
          unsetOuch2();
        } else {
          setOuch2((AccumuloSecurityException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case OUCH1:
        return getOuch1();

      case OUCH2:
        return getOuch2();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case OUCH1:
        return isSetOuch1();
      case OUCH2:
        return isSetOuch2();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof setProperty_result)
        return this.equals((setProperty_result)that);
      return false;
    }

    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();
      if (this_present_ouch1 || that_present_ouch1) {
        if (!(this_present_ouch1 && that_present_ouch1))
          return false;
        if (!this.ouch1.equals(that.ouch1))
          return false;
      }

      boolean this_present_ouch2 = true && this.isSetOuch2();
      boolean that_present_ouch2 = true && that.isSetOuch2();
      if (this_present_ouch2 || that_present_ouch2) {
        if (!(this_present_ouch2 && that_present_ouch2))
          return false;
        if (!this.ouch2.equals(that.ouch2))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
      if (isSetOuch1())
        hashCode = hashCode * 8191 + ouch1.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
      if (isSetOuch2())
        hashCode = hashCode * 8191 + ouch2.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(setProperty_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch1()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch2()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("setProperty_result(");
      boolean first = true;

      sb.append("ouch1:");
      if (this.ouch1 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch1);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch2:");
      if (this.ouch2 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch2);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class setProperty_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public setProperty_resultStandardScheme getScheme() {
        return new setProperty_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // OUCH1
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch1 = new AccumuloException();
                struct.ouch1.read(iprot);
                struct.setOuch1IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OUCH2
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch2 = new AccumuloSecurityException();
                struct.ouch2.read(iprot);
                struct.setOuch2IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, setProperty_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.ouch1 != null) {
          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
          struct.ouch1.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch2 != null) {
          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
          struct.ouch2.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class setProperty_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public setProperty_resultTupleScheme getScheme() {
        return new setProperty_resultTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetOuch2()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetOuch1()) {
          struct.ouch1.write(oprot);
        }
        if (struct.isSetOuch2()) {
          struct.ouch2.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, setProperty_result struct) throws org.apache.thrift.TException {
        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);
          struct.setOuch1IsSet(true);
        }
        if (incoming.get(1)) {
          struct.ouch2 = new AccumuloSecurityException();
          struct.ouch2.read(iprot);
          struct.setOuch2IsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("testClassLoad_args");

    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField 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 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 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 {
      LOGIN((short)1, "login"),
      CLASS_NAME((short)2, "className"),
      AS_TYPE_NAME((short)3, "asTypeName");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // LOGIN
            return LOGIN;
          case 2: // CLASS_NAME
            return CLASS_NAME;
          case 3: // AS_TYPE_NAME
            return AS_TYPE_NAME;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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 = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(testClassLoad_args.class, metaDataMap);
    }

    public testClassLoad_args() {
    }

    public testClassLoad_args(
      java.nio.ByteBuffer login,
      java.lang.String className,
      java.lang.String asTypeName)
    {
      this();
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      this.className = className;
      this.asTypeName = asTypeName;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public testClassLoad_args(testClassLoad_args other) {
      if (other.isSetLogin()) {
        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
      }
      if (other.isSetClassName()) {
        this.className = other.className;
      }
      if (other.isSetAsTypeName()) {
        this.asTypeName = other.asTypeName;
      }
    }

    public testClassLoad_args deepCopy() {
      return new testClassLoad_args(this);
    }

    @Override
    public void clear() {
      this.login = null;
      this.className = null;
      this.asTypeName = null;
    }

    public byte[] getLogin() {
      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
      return login == null ? null : login.array();
    }

    public java.nio.ByteBuffer bufferForLogin() {
      return org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    public testClassLoad_args setLogin(byte[] login) {
      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
      return this;
    }

    public testClassLoad_args setLogin(java.nio.ByteBuffer login) {
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      return this;
    }

    public void unsetLogin() {
      this.login = null;
    }

    /** Returns true if field login is set (has been assigned a value) and false otherwise */
    public boolean isSetLogin() {
      return this.login != null;
    }

    public void setLoginIsSet(boolean value) {
      if (!value) {
        this.login = null;
      }
    }

    public java.lang.String getClassName() {
      return this.className;
    }

    public testClassLoad_args setClassName(java.lang.String className) {
      this.className = className;
      return this;
    }

    public void unsetClassName() {
      this.className = null;
    }

    /** Returns true if field className is set (has been assigned a value) and false otherwise */
    public boolean isSetClassName() {
      return this.className != null;
    }

    public void setClassNameIsSet(boolean value) {
      if (!value) {
        this.className = null;
      }
    }

    public java.lang.String getAsTypeName() {
      return this.asTypeName;
    }

    public testClassLoad_args setAsTypeName(java.lang.String asTypeName) {
      this.asTypeName = asTypeName;
      return this;
    }

    public void unsetAsTypeName() {
      this.asTypeName = null;
    }

    /** Returns true if field asTypeName is set (has been assigned a value) and false otherwise */
    public boolean isSetAsTypeName() {
      return this.asTypeName != null;
    }

    public void setAsTypeNameIsSet(boolean value) {
      if (!value) {
        this.asTypeName = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case LOGIN:
        if (value == null) {
          unsetLogin();
        } else {
          if (value instanceof byte[]) {
            setLogin((byte[])value);
          } else {
            setLogin((java.nio.ByteBuffer)value);
          }
        }
        break;

      case CLASS_NAME:
        if (value == null) {
          unsetClassName();
        } else {
          setClassName((java.lang.String)value);
        }
        break;

      case AS_TYPE_NAME:
        if (value == null) {
          unsetAsTypeName();
        } else {
          setAsTypeName((java.lang.String)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case LOGIN:
        return getLogin();

      case CLASS_NAME:
        return getClassName();

      case AS_TYPE_NAME:
        return getAsTypeName();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case LOGIN:
        return isSetLogin();
      case CLASS_NAME:
        return isSetClassName();
      case AS_TYPE_NAME:
        return isSetAsTypeName();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof testClassLoad_args)
        return this.equals((testClassLoad_args)that);
      return false;
    }

    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();
      if (this_present_login || that_present_login) {
        if (!(this_present_login && that_present_login))
          return false;
        if (!this.login.equals(that.login))
          return false;
      }

      boolean this_present_className = true && this.isSetClassName();
      boolean that_present_className = true && that.isSetClassName();
      if (this_present_className || that_present_className) {
        if (!(this_present_className && that_present_className))
          return false;
        if (!this.className.equals(that.className))
          return false;
      }

      boolean this_present_asTypeName = true && this.isSetAsTypeName();
      boolean that_present_asTypeName = true && that.isSetAsTypeName();
      if (this_present_asTypeName || that_present_asTypeName) {
        if (!(this_present_asTypeName && that_present_asTypeName))
          return false;
        if (!this.asTypeName.equals(that.asTypeName))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
      if (isSetLogin())
        hashCode = hashCode * 8191 + login.hashCode();

      hashCode = hashCode * 8191 + ((isSetClassName()) ? 131071 : 524287);
      if (isSetClassName())
        hashCode = hashCode * 8191 + className.hashCode();

      hashCode = hashCode * 8191 + ((isSetAsTypeName()) ? 131071 : 524287);
      if (isSetAsTypeName())
        hashCode = hashCode * 8191 + asTypeName.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(testClassLoad_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLogin()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetClassName()).compareTo(other.isSetClassName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetClassName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.className, other.className);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetAsTypeName()).compareTo(other.isSetAsTypeName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAsTypeName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.asTypeName, other.asTypeName);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("testClassLoad_args(");
      boolean first = true;

      sb.append("login:");
      if (this.login == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.login, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("className:");
      if (this.className == null) {
        sb.append("null");
      } else {
        sb.append(this.className);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("asTypeName:");
      if (this.asTypeName == null) {
        sb.append("null");
      } else {
        sb.append(this.asTypeName);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class testClassLoad_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public testClassLoad_argsStandardScheme getScheme() {
        return new testClassLoad_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // LOGIN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.login = iprot.readBinary();
                struct.setLoginIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // CLASS_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.className = iprot.readString();
                struct.setClassNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // AS_TYPE_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.asTypeName = iprot.readString();
                struct.setAsTypeNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, testClassLoad_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.login != null) {
          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
          oprot.writeBinary(struct.login);
          oprot.writeFieldEnd();
        }
        if (struct.className != null) {
          oprot.writeFieldBegin(CLASS_NAME_FIELD_DESC);
          oprot.writeString(struct.className);
          oprot.writeFieldEnd();
        }
        if (struct.asTypeName != null) {
          oprot.writeFieldBegin(AS_TYPE_NAME_FIELD_DESC);
          oprot.writeString(struct.asTypeName);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class testClassLoad_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public testClassLoad_argsTupleScheme getScheme() {
        return new testClassLoad_argsTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetClassName()) {
          optionals.set(1);
        }
        if (struct.isSetAsTypeName()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetLogin()) {
          oprot.writeBinary(struct.login);
        }
        if (struct.isSetClassName()) {
          oprot.writeString(struct.className);
        }
        if (struct.isSetAsTypeName()) {
          oprot.writeString(struct.asTypeName);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, testClassLoad_args struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.className = iprot.readString();
          struct.setClassNameIsSet(true);
        }
        if (incoming.get(2)) {
          struct.asTypeName = iprot.readString();
          struct.setAsTypeNameIsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("testClassLoad_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.BOOL, (short)0);
    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);

    private static final org.apache.thrift.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
    public AccumuloSecurityException ouch2; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      OUCH1((short)1, "ouch1"),
      OUCH2((short)2, "ouch2");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // OUCH1
            return OUCH1;
          case 2: // OUCH2
            return OUCH2;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __SUCCESS_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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.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);
    }

    public testClassLoad_result() {
    }

    public testClassLoad_result(
      boolean success,
      AccumuloException ouch1,
      AccumuloSecurityException ouch2)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
      this.ouch1 = ouch1;
      this.ouch2 = ouch2;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public testClassLoad_result(testClassLoad_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
      if (other.isSetOuch1()) {
        this.ouch1 = new AccumuloException(other.ouch1);
      }
      if (other.isSetOuch2()) {
        this.ouch2 = new AccumuloSecurityException(other.ouch2);
      }
    }

    public testClassLoad_result deepCopy() {
      return new testClassLoad_result(this);
    }

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
      this.ouch1 = null;
      this.ouch2 = null;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public testClassLoad_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

    public void unsetSuccess() {
      __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 org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    public void setSuccessIsSet(boolean value) {
      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
    }

    public AccumuloException getOuch1() {
      return this.ouch1;
    }

    public testClassLoad_result setOuch1(AccumuloException ouch1) {
      this.ouch1 = ouch1;
      return this;
    }

    public void unsetOuch1() {
      this.ouch1 = null;
    }

    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch1() {
      return this.ouch1 != null;
    }

    public void setOuch1IsSet(boolean value) {
      if (!value) {
        this.ouch1 = null;
      }
    }

    public AccumuloSecurityException getOuch2() {
      return this.ouch2;
    }

    public testClassLoad_result setOuch2(AccumuloSecurityException ouch2) {
      this.ouch2 = ouch2;
      return this;
    }

    public void unsetOuch2() {
      this.ouch2 = null;
    }

    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch2() {
      return this.ouch2 != null;
    }

    public void setOuch2IsSet(boolean value) {
      if (!value) {
        this.ouch2 = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.lang.Boolean)value);
        }
        break;

      case OUCH1:
        if (value == null) {
          unsetOuch1();
        } else {
          setOuch1((AccumuloException)value);
        }
        break;

      case OUCH2:
        if (value == null) {
          unsetOuch2();
        } else {
          setOuch2((AccumuloSecurityException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return isSuccess();

      case OUCH1:
        return getOuch1();

      case OUCH2:
        return getOuch2();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case OUCH1:
        return isSetOuch1();
      case OUCH2:
        return isSetOuch2();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof testClassLoad_result)
        return this.equals((testClassLoad_result)that);
      return false;
    }

    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;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      boolean this_present_ouch1 = true && this.isSetOuch1();
      boolean that_present_ouch1 = true && that.isSetOuch1();
      if (this_present_ouch1 || that_present_ouch1) {
        if (!(this_present_ouch1 && that_present_ouch1))
          return false;
        if (!this.ouch1.equals(that.ouch1))
          return false;
      }

      boolean this_present_ouch2 = true && this.isSetOuch2();
      boolean that_present_ouch2 = true && that.isSetOuch2();
      if (this_present_ouch2 || that_present_ouch2) {
        if (!(this_present_ouch2 && that_present_ouch2))
          return false;
        if (!this.ouch2.equals(that.ouch2))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((success) ? 131071 : 524287);

      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
      if (isSetOuch1())
        hashCode = hashCode * 8191 + ouch1.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
      if (isSetOuch2())
        hashCode = hashCode * 8191 + ouch2.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(testClassLoad_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch1()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch2()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("testClassLoad_result(");
      boolean first = true;

      sb.append("success:");
      sb.append(this.success);
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch1:");
      if (this.ouch1 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch1);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch2:");
      if (this.ouch2 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch2);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, 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;
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class testClassLoad_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public testClassLoad_resultStandardScheme getScheme() {
        return new testClassLoad_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
                struct.success = iprot.readBool();
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // OUCH1
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch1 = new AccumuloException();
                struct.ouch1.read(iprot);
                struct.setOuch1IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OUCH2
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch2 = new AccumuloSecurityException();
                struct.ouch2.read(iprot);
                struct.setOuch2IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, testClassLoad_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.isSetSuccess()) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          oprot.writeBool(struct.success);
          oprot.writeFieldEnd();
        }
        if (struct.ouch1 != null) {
          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
          struct.ouch1.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch2 != null) {
          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
          struct.ouch2.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class testClassLoad_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public testClassLoad_resultTupleScheme getScheme() {
        return new testClassLoad_resultTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetOuch1()) {
          optionals.set(1);
        }
        if (struct.isSetOuch2()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
        if (struct.isSetOuch1()) {
          struct.ouch1.write(oprot);
        }
        if (struct.isSetOuch2()) {
          struct.ouch2.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, testClassLoad_result struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.ouch1 = new AccumuloException();
          struct.ouch1.read(iprot);
          struct.setOuch1IsSet(true);
        }
        if (incoming.get(2)) {
          struct.ouch2 = new AccumuloSecurityException();
          struct.ouch2.read(iprot);
          struct.setOuch2IsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("authenticateUser_args");

    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField USER_FIELD_DESC = new org.apache.thrift.protocol.TField("user", org.apache.thrift.protocol.TType.STRING, (short)2);
    private static final org.apache.thrift.protocol.TField PROPERTIES_FIELD_DESC = new org.apache.thrift.protocol.TField("properties", org.apache.thrift.protocol.TType.MAP, (short)3);

    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 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 {
      LOGIN((short)1, "login"),
      USER((short)2, "user"),
      PROPERTIES((short)3, "properties");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // LOGIN
            return LOGIN;
          case 2: // USER
            return USER;
          case 3: // PROPERTIES
            return PROPERTIES;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.PROPERTIES, new org.apache.thrift.meta_data.FieldMetaData("properties", 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 = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(authenticateUser_args.class, metaDataMap);
    }

    public authenticateUser_args() {
    }

    public authenticateUser_args(
      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);
      this.user = user;
      this.properties = properties;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public authenticateUser_args(authenticateUser_args other) {
      if (other.isSetLogin()) {
        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
      }
      if (other.isSetUser()) {
        this.user = other.user;
      }
      if (other.isSetProperties()) {
        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;
      }
    }

    public authenticateUser_args deepCopy() {
      return new authenticateUser_args(this);
    }

    @Override
    public void clear() {
      this.login = null;
      this.user = null;
      this.properties = null;
    }

    public byte[] getLogin() {
      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
      return login == null ? null : login.array();
    }

    public java.nio.ByteBuffer bufferForLogin() {
      return org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    public authenticateUser_args setLogin(byte[] login) {
      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
      return this;
    }

    public authenticateUser_args setLogin(java.nio.ByteBuffer login) {
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      return this;
    }

    public void unsetLogin() {
      this.login = null;
    }

    /** Returns true if field login is set (has been assigned a value) and false otherwise */
    public boolean isSetLogin() {
      return this.login != null;
    }

    public void setLoginIsSet(boolean value) {
      if (!value) {
        this.login = null;
      }
    }

    public java.lang.String getUser() {
      return this.user;
    }

    public authenticateUser_args setUser(java.lang.String user) {
      this.user = user;
      return this;
    }

    public void unsetUser() {
      this.user = null;
    }

    /** Returns true if field user is set (has been assigned a value) and false otherwise */
    public boolean isSetUser() {
      return this.user != null;
    }

    public void setUserIsSet(boolean value) {
      if (!value) {
        this.user = null;
      }
    }

    public int getPropertiesSize() {
      return (this.properties == null) ? 0 : this.properties.size();
    }

    public void putToProperties(java.lang.String key, java.lang.String val) {
      if (this.properties == null) {
        this.properties = new java.util.HashMap<java.lang.String,java.lang.String>();
      }
      this.properties.put(key, val);
    }

    public java.util.Map<java.lang.String,java.lang.String> getProperties() {
      return this.properties;
    }

    public authenticateUser_args setProperties(java.util.Map<java.lang.String,java.lang.String> properties) {
      this.properties = properties;
      return this;
    }

    public void unsetProperties() {
      this.properties = null;
    }

    /** Returns true if field properties is set (has been assigned a value) and false otherwise */
    public boolean isSetProperties() {
      return this.properties != null;
    }

    public void setPropertiesIsSet(boolean value) {
      if (!value) {
        this.properties = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case LOGIN:
        if (value == null) {
          unsetLogin();
        } else {
          if (value instanceof byte[]) {
            setLogin((byte[])value);
          } else {
            setLogin((java.nio.ByteBuffer)value);
          }
        }
        break;

      case USER:
        if (value == null) {
          unsetUser();
        } else {
          setUser((java.lang.String)value);
        }
        break;

      case PROPERTIES:
        if (value == null) {
          unsetProperties();
        } else {
          setProperties((java.util.Map<java.lang.String,java.lang.String>)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case LOGIN:
        return getLogin();

      case USER:
        return getUser();

      case PROPERTIES:
        return getProperties();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case LOGIN:
        return isSetLogin();
      case USER:
        return isSetUser();
      case PROPERTIES:
        return isSetProperties();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof authenticateUser_args)
        return this.equals((authenticateUser_args)that);
      return false;
    }

    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();
      if (this_present_login || that_present_login) {
        if (!(this_present_login && that_present_login))
          return false;
        if (!this.login.equals(that.login))
          return false;
      }

      boolean this_present_user = true && this.isSetUser();
      boolean that_present_user = true && that.isSetUser();
      if (this_present_user || that_present_user) {
        if (!(this_present_user && that_present_user))
          return false;
        if (!this.user.equals(that.user))
          return false;
      }

      boolean this_present_properties = true && this.isSetProperties();
      boolean that_present_properties = true && that.isSetProperties();
      if (this_present_properties || that_present_properties) {
        if (!(this_present_properties && that_present_properties))
          return false;
        if (!this.properties.equals(that.properties))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
      if (isSetLogin())
        hashCode = hashCode * 8191 + login.hashCode();

      hashCode = hashCode * 8191 + ((isSetUser()) ? 131071 : 524287);
      if (isSetUser())
        hashCode = hashCode * 8191 + user.hashCode();

      hashCode = hashCode * 8191 + ((isSetProperties()) ? 131071 : 524287);
      if (isSetProperties())
        hashCode = hashCode * 8191 + properties.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(authenticateUser_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLogin()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetUser()).compareTo(other.isSetUser());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetUser()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.user, other.user);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetProperties()).compareTo(other.isSetProperties());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetProperties()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.properties, other.properties);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("authenticateUser_args(");
      boolean first = true;

      sb.append("login:");
      if (this.login == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.login, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("user:");
      if (this.user == null) {
        sb.append("null");
      } else {
        sb.append(this.user);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("properties:");
      if (this.properties == null) {
        sb.append("null");
      } else {
        sb.append(this.properties);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class authenticateUser_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public authenticateUser_argsStandardScheme getScheme() {
        return new authenticateUser_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // LOGIN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.login = iprot.readBinary();
                struct.setLoginIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // USER
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.user = iprot.readString();
                struct.setUserIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // PROPERTIES
              if (schemeField.type == org.apache.thrift.protocol.TType.MAP) {
                {
                  org.apache.thrift.protocol.TMap _map408 = iprot.readMapBegin();
                  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();
                    _val410 = iprot.readString();
                    struct.properties.put(_key409, _val410);
                  }
                  iprot.readMapEnd();
                }
                struct.setPropertiesIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, authenticateUser_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.login != null) {
          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
          oprot.writeBinary(struct.login);
          oprot.writeFieldEnd();
        }
        if (struct.user != null) {
          oprot.writeFieldBegin(USER_FIELD_DESC);
          oprot.writeString(struct.user);
          oprot.writeFieldEnd();
        }
        if (struct.properties != null) {
          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 (java.util.Map.Entry<java.lang.String, java.lang.String> _iter412 : struct.properties.entrySet())
            {
              oprot.writeString(_iter412.getKey());
              oprot.writeString(_iter412.getValue());
            }
            oprot.writeMapEnd();
          }
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    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 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 {
        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);
        }
        if (struct.isSetUser()) {
          optionals.set(1);
        }
        if (struct.isSetProperties()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetLogin()) {
          oprot.writeBinary(struct.login);
        }
        if (struct.isSetUser()) {
          oprot.writeString(struct.user);
        }
        if (struct.isSetProperties()) {
          {
            oprot.writeI32(struct.properties.size());
            for (java.util.Map.Entry<java.lang.String, java.lang.String> _iter413 : struct.properties.entrySet())
            {
              oprot.writeString(_iter413.getKey());
              oprot.writeString(_iter413.getValue());
            }
          }
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, authenticateUser_args struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.user = iprot.readString();
          struct.setUserIsSet(true);
        }
        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 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();
              _val416 = iprot.readString();
              struct.properties.put(_key415, _val416);
            }
          }
          struct.setPropertiesIsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("authenticateUser_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.BOOL, (short)0);
    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);

    private static final org.apache.thrift.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
    public AccumuloSecurityException ouch2; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      OUCH1((short)1, "ouch1"),
      OUCH2((short)2, "ouch2");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // OUCH1
            return OUCH1;
          case 2: // OUCH2
            return OUCH2;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __SUCCESS_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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.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);
    }

    public authenticateUser_result() {
    }

    public authenticateUser_result(
      boolean success,
      AccumuloException ouch1,
      AccumuloSecurityException ouch2)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
      this.ouch1 = ouch1;
      this.ouch2 = ouch2;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public authenticateUser_result(authenticateUser_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
      if (other.isSetOuch1()) {
        this.ouch1 = new AccumuloException(other.ouch1);
      }
      if (other.isSetOuch2()) {
        this.ouch2 = new AccumuloSecurityException(other.ouch2);
      }
    }

    public authenticateUser_result deepCopy() {
      return new authenticateUser_result(this);
    }

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
      this.ouch1 = null;
      this.ouch2 = null;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public authenticateUser_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

    public void unsetSuccess() {
      __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 org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    public void setSuccessIsSet(boolean value) {
      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
    }

    public AccumuloException getOuch1() {
      return this.ouch1;
    }

    public authenticateUser_result setOuch1(AccumuloException ouch1) {
      this.ouch1 = ouch1;
      return this;
    }

    public void unsetOuch1() {
      this.ouch1 = null;
    }

    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch1() {
      return this.ouch1 != null;
    }

    public void setOuch1IsSet(boolean value) {
      if (!value) {
        this.ouch1 = null;
      }
    }

    public AccumuloSecurityException getOuch2() {
      return this.ouch2;
    }

    public authenticateUser_result setOuch2(AccumuloSecurityException ouch2) {
      this.ouch2 = ouch2;
      return this;
    }

    public void unsetOuch2() {
      this.ouch2 = null;
    }

    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch2() {
      return this.ouch2 != null;
    }

    public void setOuch2IsSet(boolean value) {
      if (!value) {
        this.ouch2 = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.lang.Boolean)value);
        }
        break;

      case OUCH1:
        if (value == null) {
          unsetOuch1();
        } else {
          setOuch1((AccumuloException)value);
        }
        break;

      case OUCH2:
        if (value == null) {
          unsetOuch2();
        } else {
          setOuch2((AccumuloSecurityException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return isSuccess();

      case OUCH1:
        return getOuch1();

      case OUCH2:
        return getOuch2();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case OUCH1:
        return isSetOuch1();
      case OUCH2:
        return isSetOuch2();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof authenticateUser_result)
        return this.equals((authenticateUser_result)that);
      return false;
    }

    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;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      boolean this_present_ouch1 = true && this.isSetOuch1();
      boolean that_present_ouch1 = true && that.isSetOuch1();
      if (this_present_ouch1 || that_present_ouch1) {
        if (!(this_present_ouch1 && that_present_ouch1))
          return false;
        if (!this.ouch1.equals(that.ouch1))
          return false;
      }

      boolean this_present_ouch2 = true && this.isSetOuch2();
      boolean that_present_ouch2 = true && that.isSetOuch2();
      if (this_present_ouch2 || that_present_ouch2) {
        if (!(this_present_ouch2 && that_present_ouch2))
          return false;
        if (!this.ouch2.equals(that.ouch2))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((success) ? 131071 : 524287);

      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
      if (isSetOuch1())
        hashCode = hashCode * 8191 + ouch1.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
      if (isSetOuch2())
        hashCode = hashCode * 8191 + ouch2.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(authenticateUser_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch1()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch2()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("authenticateUser_result(");
      boolean first = true;

      sb.append("success:");
      sb.append(this.success);
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch1:");
      if (this.ouch1 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch1);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch2:");
      if (this.ouch2 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch2);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, 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;
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class authenticateUser_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public authenticateUser_resultStandardScheme getScheme() {
        return new authenticateUser_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
                struct.success = iprot.readBool();
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // OUCH1
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch1 = new AccumuloException();
                struct.ouch1.read(iprot);
                struct.setOuch1IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OUCH2
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch2 = new AccumuloSecurityException();
                struct.ouch2.read(iprot);
                struct.setOuch2IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, authenticateUser_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.isSetSuccess()) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          oprot.writeBool(struct.success);
          oprot.writeFieldEnd();
        }
        if (struct.ouch1 != null) {
          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
          struct.ouch1.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch2 != null) {
          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
          struct.ouch2.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class authenticateUser_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public authenticateUser_resultTupleScheme getScheme() {
        return new authenticateUser_resultTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetOuch1()) {
          optionals.set(1);
        }
        if (struct.isSetOuch2()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
        if (struct.isSetOuch1()) {
          struct.ouch1.write(oprot);
        }
        if (struct.isSetOuch2()) {
          struct.ouch2.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, authenticateUser_result struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.ouch1 = new AccumuloException();
          struct.ouch1.read(iprot);
          struct.setOuch1IsSet(true);
        }
        if (incoming.get(2)) {
          struct.ouch2 = new AccumuloSecurityException();
          struct.ouch2.read(iprot);
          struct.setOuch2IsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("changeUserAuthorizations_args");

    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField USER_FIELD_DESC = new org.apache.thrift.protocol.TField("user", org.apache.thrift.protocol.TType.STRING, (short)2);
    private static final org.apache.thrift.protocol.TField AUTHORIZATIONS_FIELD_DESC = new org.apache.thrift.protocol.TField("authorizations", org.apache.thrift.protocol.TType.SET, (short)3);

    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 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 {
      LOGIN((short)1, "login"),
      USER((short)2, "user"),
      AUTHORIZATIONS((short)3, "authorizations");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // LOGIN
            return LOGIN;
          case 2: // USER
            return USER;
          case 3: // AUTHORIZATIONS
            return AUTHORIZATIONS;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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 = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(changeUserAuthorizations_args.class, metaDataMap);
    }

    public changeUserAuthorizations_args() {
    }

    public changeUserAuthorizations_args(
      java.nio.ByteBuffer login,
      java.lang.String user,
      java.util.Set<java.nio.ByteBuffer> authorizations)
    {
      this();
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      this.user = user;
      this.authorizations = authorizations;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public changeUserAuthorizations_args(changeUserAuthorizations_args other) {
      if (other.isSetLogin()) {
        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
      }
      if (other.isSetUser()) {
        this.user = other.user;
      }
      if (other.isSetAuthorizations()) {
        java.util.Set<java.nio.ByteBuffer> __this__authorizations = new java.util.HashSet<java.nio.ByteBuffer>(other.authorizations);
        this.authorizations = __this__authorizations;
      }
    }

    public changeUserAuthorizations_args deepCopy() {
      return new changeUserAuthorizations_args(this);
    }

    @Override
    public void clear() {
      this.login = null;
      this.user = null;
      this.authorizations = null;
    }

    public byte[] getLogin() {
      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
      return login == null ? null : login.array();
    }

    public java.nio.ByteBuffer bufferForLogin() {
      return org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    public changeUserAuthorizations_args setLogin(byte[] login) {
      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
      return this;
    }

    public changeUserAuthorizations_args setLogin(java.nio.ByteBuffer login) {
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      return this;
    }

    public void unsetLogin() {
      this.login = null;
    }

    /** Returns true if field login is set (has been assigned a value) and false otherwise */
    public boolean isSetLogin() {
      return this.login != null;
    }

    public void setLoginIsSet(boolean value) {
      if (!value) {
        this.login = null;
      }
    }

    public java.lang.String getUser() {
      return this.user;
    }

    public changeUserAuthorizations_args setUser(java.lang.String user) {
      this.user = user;
      return this;
    }

    public void unsetUser() {
      this.user = null;
    }

    /** Returns true if field user is set (has been assigned a value) and false otherwise */
    public boolean isSetUser() {
      return this.user != null;
    }

    public void setUserIsSet(boolean value) {
      if (!value) {
        this.user = null;
      }
    }

    public int getAuthorizationsSize() {
      return (this.authorizations == null) ? 0 : this.authorizations.size();
    }

    public java.util.Iterator<java.nio.ByteBuffer> getAuthorizationsIterator() {
      return (this.authorizations == null) ? null : this.authorizations.iterator();
    }

    public void addToAuthorizations(java.nio.ByteBuffer elem) {
      if (this.authorizations == null) {
        this.authorizations = new java.util.HashSet<java.nio.ByteBuffer>();
      }
      this.authorizations.add(elem);
    }

    public java.util.Set<java.nio.ByteBuffer> getAuthorizations() {
      return this.authorizations;
    }

    public changeUserAuthorizations_args setAuthorizations(java.util.Set<java.nio.ByteBuffer> authorizations) {
      this.authorizations = authorizations;
      return this;
    }

    public void unsetAuthorizations() {
      this.authorizations = null;
    }

    /** Returns true if field authorizations is set (has been assigned a value) and false otherwise */
    public boolean isSetAuthorizations() {
      return this.authorizations != null;
    }

    public void setAuthorizationsIsSet(boolean value) {
      if (!value) {
        this.authorizations = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case LOGIN:
        if (value == null) {
          unsetLogin();
        } else {
          if (value instanceof byte[]) {
            setLogin((byte[])value);
          } else {
            setLogin((java.nio.ByteBuffer)value);
          }
        }
        break;

      case USER:
        if (value == null) {
          unsetUser();
        } else {
          setUser((java.lang.String)value);
        }
        break;

      case AUTHORIZATIONS:
        if (value == null) {
          unsetAuthorizations();
        } else {
          setAuthorizations((java.util.Set<java.nio.ByteBuffer>)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case LOGIN:
        return getLogin();

      case USER:
        return getUser();

      case AUTHORIZATIONS:
        return getAuthorizations();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case LOGIN:
        return isSetLogin();
      case USER:
        return isSetUser();
      case AUTHORIZATIONS:
        return isSetAuthorizations();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof changeUserAuthorizations_args)
        return this.equals((changeUserAuthorizations_args)that);
      return false;
    }

    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();
      if (this_present_login || that_present_login) {
        if (!(this_present_login && that_present_login))
          return false;
        if (!this.login.equals(that.login))
          return false;
      }

      boolean this_present_user = true && this.isSetUser();
      boolean that_present_user = true && that.isSetUser();
      if (this_present_user || that_present_user) {
        if (!(this_present_user && that_present_user))
          return false;
        if (!this.user.equals(that.user))
          return false;
      }

      boolean this_present_authorizations = true && this.isSetAuthorizations();
      boolean that_present_authorizations = true && that.isSetAuthorizations();
      if (this_present_authorizations || that_present_authorizations) {
        if (!(this_present_authorizations && that_present_authorizations))
          return false;
        if (!this.authorizations.equals(that.authorizations))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
      if (isSetLogin())
        hashCode = hashCode * 8191 + login.hashCode();

      hashCode = hashCode * 8191 + ((isSetUser()) ? 131071 : 524287);
      if (isSetUser())
        hashCode = hashCode * 8191 + user.hashCode();

      hashCode = hashCode * 8191 + ((isSetAuthorizations()) ? 131071 : 524287);
      if (isSetAuthorizations())
        hashCode = hashCode * 8191 + authorizations.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(changeUserAuthorizations_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLogin()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetUser()).compareTo(other.isSetUser());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetUser()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.user, other.user);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetAuthorizations()).compareTo(other.isSetAuthorizations());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAuthorizations()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.authorizations, other.authorizations);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("changeUserAuthorizations_args(");
      boolean first = true;

      sb.append("login:");
      if (this.login == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.login, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("user:");
      if (this.user == null) {
        sb.append("null");
      } else {
        sb.append(this.user);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("authorizations:");
      if (this.authorizations == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.authorizations, sb);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class changeUserAuthorizations_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public changeUserAuthorizations_argsStandardScheme getScheme() {
        return new changeUserAuthorizations_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // LOGIN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.login = iprot.readBinary();
                struct.setLoginIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // USER
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.user = iprot.readString();
                struct.setUserIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // AUTHORIZATIONS
              if (schemeField.type == org.apache.thrift.protocol.TType.SET) {
                {
                  org.apache.thrift.protocol.TSet _set418 = iprot.readSetBegin();
                  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();
                    struct.authorizations.add(_elem419);
                  }
                  iprot.readSetEnd();
                }
                struct.setAuthorizationsIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, changeUserAuthorizations_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.login != null) {
          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
          oprot.writeBinary(struct.login);
          oprot.writeFieldEnd();
        }
        if (struct.user != null) {
          oprot.writeFieldBegin(USER_FIELD_DESC);
          oprot.writeString(struct.user);
          oprot.writeFieldEnd();
        }
        if (struct.authorizations != null) {
          oprot.writeFieldBegin(AUTHORIZATIONS_FIELD_DESC);
          {
            oprot.writeSetBegin(new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRING, struct.authorizations.size()));
            for (java.nio.ByteBuffer _iter421 : struct.authorizations)
            {
              oprot.writeBinary(_iter421);
            }
            oprot.writeSetEnd();
          }
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    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 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 {
        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);
        }
        if (struct.isSetUser()) {
          optionals.set(1);
        }
        if (struct.isSetAuthorizations()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetLogin()) {
          oprot.writeBinary(struct.login);
        }
        if (struct.isSetUser()) {
          oprot.writeString(struct.user);
        }
        if (struct.isSetAuthorizations()) {
          {
            oprot.writeI32(struct.authorizations.size());
            for (java.nio.ByteBuffer _iter422 : struct.authorizations)
            {
              oprot.writeBinary(_iter422);
            }
          }
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, changeUserAuthorizations_args struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.user = iprot.readString();
          struct.setUserIsSet(true);
        }
        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 java.util.HashSet<java.nio.ByteBuffer>(2*_set423.size);
            java.nio.ByteBuffer _elem424;
            for (int _i425 = 0; _i425 < _set423.size; ++_i425)
            {
              _elem424 = iprot.readBinary();
              struct.authorizations.add(_elem424);
            }
          }
          struct.setAuthorizationsIsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("changeUserAuthorizations_result");

    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);

    private static final org.apache.thrift.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

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      OUCH1((short)1, "ouch1"),
      OUCH2((short)2, "ouch2");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // OUCH1
            return OUCH1;
          case 2: // OUCH2
            return OUCH2;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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.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);
    }

    public changeUserAuthorizations_result() {
    }

    public changeUserAuthorizations_result(
      AccumuloException ouch1,
      AccumuloSecurityException ouch2)
    {
      this();
      this.ouch1 = ouch1;
      this.ouch2 = ouch2;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public changeUserAuthorizations_result(changeUserAuthorizations_result other) {
      if (other.isSetOuch1()) {
        this.ouch1 = new AccumuloException(other.ouch1);
      }
      if (other.isSetOuch2()) {
        this.ouch2 = new AccumuloSecurityException(other.ouch2);
      }
    }

    public changeUserAuthorizations_result deepCopy() {
      return new changeUserAuthorizations_result(this);
    }

    @Override
    public void clear() {
      this.ouch1 = null;
      this.ouch2 = null;
    }

    public AccumuloException getOuch1() {
      return this.ouch1;
    }

    public changeUserAuthorizations_result setOuch1(AccumuloException ouch1) {
      this.ouch1 = ouch1;
      return this;
    }

    public void unsetOuch1() {
      this.ouch1 = null;
    }

    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch1() {
      return this.ouch1 != null;
    }

    public void setOuch1IsSet(boolean value) {
      if (!value) {
        this.ouch1 = null;
      }
    }

    public AccumuloSecurityException getOuch2() {
      return this.ouch2;
    }

    public changeUserAuthorizations_result setOuch2(AccumuloSecurityException ouch2) {
      this.ouch2 = ouch2;
      return this;
    }

    public void unsetOuch2() {
      this.ouch2 = null;
    }

    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch2() {
      return this.ouch2 != null;
    }

    public void setOuch2IsSet(boolean value) {
      if (!value) {
        this.ouch2 = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case OUCH1:
        if (value == null) {
          unsetOuch1();
        } else {
          setOuch1((AccumuloException)value);
        }
        break;

      case OUCH2:
        if (value == null) {
          unsetOuch2();
        } else {
          setOuch2((AccumuloSecurityException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case OUCH1:
        return getOuch1();

      case OUCH2:
        return getOuch2();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case OUCH1:
        return isSetOuch1();
      case OUCH2:
        return isSetOuch2();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof changeUserAuthorizations_result)
        return this.equals((changeUserAuthorizations_result)that);
      return false;
    }

    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();
      if (this_present_ouch1 || that_present_ouch1) {
        if (!(this_present_ouch1 && that_present_ouch1))
          return false;
        if (!this.ouch1.equals(that.ouch1))
          return false;
      }

      boolean this_present_ouch2 = true && this.isSetOuch2();
      boolean that_present_ouch2 = true && that.isSetOuch2();
      if (this_present_ouch2 || that_present_ouch2) {
        if (!(this_present_ouch2 && that_present_ouch2))
          return false;
        if (!this.ouch2.equals(that.ouch2))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
      if (isSetOuch1())
        hashCode = hashCode * 8191 + ouch1.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
      if (isSetOuch2())
        hashCode = hashCode * 8191 + ouch2.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(changeUserAuthorizations_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch1()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch2()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("changeUserAuthorizations_result(");
      boolean first = true;

      sb.append("ouch1:");
      if (this.ouch1 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch1);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch2:");
      if (this.ouch2 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch2);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class changeUserAuthorizations_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public changeUserAuthorizations_resultStandardScheme getScheme() {
        return new changeUserAuthorizations_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // OUCH1
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch1 = new AccumuloException();
                struct.ouch1.read(iprot);
                struct.setOuch1IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OUCH2
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch2 = new AccumuloSecurityException();
                struct.ouch2.read(iprot);
                struct.setOuch2IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, changeUserAuthorizations_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.ouch1 != null) {
          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
          struct.ouch1.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch2 != null) {
          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
          struct.ouch2.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class changeUserAuthorizations_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public changeUserAuthorizations_resultTupleScheme getScheme() {
        return new changeUserAuthorizations_resultTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetOuch2()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetOuch1()) {
          struct.ouch1.write(oprot);
        }
        if (struct.isSetOuch2()) {
          struct.ouch2.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, changeUserAuthorizations_result struct) throws org.apache.thrift.TException {
        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);
          struct.setOuch1IsSet(true);
        }
        if (incoming.get(1)) {
          struct.ouch2 = new AccumuloSecurityException();
          struct.ouch2.read(iprot);
          struct.setOuch2IsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("changeLocalUserPassword_args");

    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField USER_FIELD_DESC = new org.apache.thrift.protocol.TField("user", org.apache.thrift.protocol.TType.STRING, (short)2);
    private static final org.apache.thrift.protocol.TField PASSWORD_FIELD_DESC = new org.apache.thrift.protocol.TField("password", org.apache.thrift.protocol.TType.STRING, (short)3);

    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 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 {
      LOGIN((short)1, "login"),
      USER((short)2, "user"),
      PASSWORD((short)3, "password");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // LOGIN
            return LOGIN;
          case 2: // USER
            return USER;
          case 3: // PASSWORD
            return PASSWORD;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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 = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(changeLocalUserPassword_args.class, metaDataMap);
    }

    public changeLocalUserPassword_args() {
    }

    public changeLocalUserPassword_args(
      java.nio.ByteBuffer login,
      java.lang.String user,
      java.nio.ByteBuffer password)
    {
      this();
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      this.user = user;
      this.password = org.apache.thrift.TBaseHelper.copyBinary(password);
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public changeLocalUserPassword_args(changeLocalUserPassword_args other) {
      if (other.isSetLogin()) {
        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
      }
      if (other.isSetUser()) {
        this.user = other.user;
      }
      if (other.isSetPassword()) {
        this.password = org.apache.thrift.TBaseHelper.copyBinary(other.password);
      }
    }

    public changeLocalUserPassword_args deepCopy() {
      return new changeLocalUserPassword_args(this);
    }

    @Override
    public void clear() {
      this.login = null;
      this.user = null;
      this.password = null;
    }

    public byte[] getLogin() {
      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
      return login == null ? null : login.array();
    }

    public java.nio.ByteBuffer bufferForLogin() {
      return org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    public changeLocalUserPassword_args setLogin(byte[] login) {
      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
      return this;
    }

    public changeLocalUserPassword_args setLogin(java.nio.ByteBuffer login) {
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      return this;
    }

    public void unsetLogin() {
      this.login = null;
    }

    /** Returns true if field login is set (has been assigned a value) and false otherwise */
    public boolean isSetLogin() {
      return this.login != null;
    }

    public void setLoginIsSet(boolean value) {
      if (!value) {
        this.login = null;
      }
    }

    public java.lang.String getUser() {
      return this.user;
    }

    public changeLocalUserPassword_args setUser(java.lang.String user) {
      this.user = user;
      return this;
    }

    public void unsetUser() {
      this.user = null;
    }

    /** Returns true if field user is set (has been assigned a value) and false otherwise */
    public boolean isSetUser() {
      return this.user != null;
    }

    public void setUserIsSet(boolean value) {
      if (!value) {
        this.user = null;
      }
    }

    public byte[] getPassword() {
      setPassword(org.apache.thrift.TBaseHelper.rightSize(password));
      return password == null ? null : password.array();
    }

    public java.nio.ByteBuffer bufferForPassword() {
      return org.apache.thrift.TBaseHelper.copyBinary(password);
    }

    public changeLocalUserPassword_args setPassword(byte[] password) {
      this.password = password == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(password.clone());
      return this;
    }

    public changeLocalUserPassword_args setPassword(java.nio.ByteBuffer password) {
      this.password = org.apache.thrift.TBaseHelper.copyBinary(password);
      return this;
    }

    public void unsetPassword() {
      this.password = null;
    }

    /** Returns true if field password is set (has been assigned a value) and false otherwise */
    public boolean isSetPassword() {
      return this.password != null;
    }

    public void setPasswordIsSet(boolean value) {
      if (!value) {
        this.password = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case LOGIN:
        if (value == null) {
          unsetLogin();
        } else {
          if (value instanceof byte[]) {
            setLogin((byte[])value);
          } else {
            setLogin((java.nio.ByteBuffer)value);
          }
        }
        break;

      case USER:
        if (value == null) {
          unsetUser();
        } else {
          setUser((java.lang.String)value);
        }
        break;

      case PASSWORD:
        if (value == null) {
          unsetPassword();
        } else {
          if (value instanceof byte[]) {
            setPassword((byte[])value);
          } else {
            setPassword((java.nio.ByteBuffer)value);
          }
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case LOGIN:
        return getLogin();

      case USER:
        return getUser();

      case PASSWORD:
        return getPassword();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case LOGIN:
        return isSetLogin();
      case USER:
        return isSetUser();
      case PASSWORD:
        return isSetPassword();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof changeLocalUserPassword_args)
        return this.equals((changeLocalUserPassword_args)that);
      return false;
    }

    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();
      if (this_present_login || that_present_login) {
        if (!(this_present_login && that_present_login))
          return false;
        if (!this.login.equals(that.login))
          return false;
      }

      boolean this_present_user = true && this.isSetUser();
      boolean that_present_user = true && that.isSetUser();
      if (this_present_user || that_present_user) {
        if (!(this_present_user && that_present_user))
          return false;
        if (!this.user.equals(that.user))
          return false;
      }

      boolean this_present_password = true && this.isSetPassword();
      boolean that_present_password = true && that.isSetPassword();
      if (this_present_password || that_present_password) {
        if (!(this_present_password && that_present_password))
          return false;
        if (!this.password.equals(that.password))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
      if (isSetLogin())
        hashCode = hashCode * 8191 + login.hashCode();

      hashCode = hashCode * 8191 + ((isSetUser()) ? 131071 : 524287);
      if (isSetUser())
        hashCode = hashCode * 8191 + user.hashCode();

      hashCode = hashCode * 8191 + ((isSetPassword()) ? 131071 : 524287);
      if (isSetPassword())
        hashCode = hashCode * 8191 + password.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(changeLocalUserPassword_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLogin()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetUser()).compareTo(other.isSetUser());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetUser()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.user, other.user);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetPassword()).compareTo(other.isSetPassword());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetPassword()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.password, other.password);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("changeLocalUserPassword_args(");
      boolean first = true;

      sb.append("login:");
      if (this.login == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.login, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("user:");
      if (this.user == null) {
        sb.append("null");
      } else {
        sb.append(this.user);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("password:");
      if (this.password == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.password, sb);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class changeLocalUserPassword_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public changeLocalUserPassword_argsStandardScheme getScheme() {
        return new changeLocalUserPassword_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // LOGIN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.login = iprot.readBinary();
                struct.setLoginIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // USER
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.user = iprot.readString();
                struct.setUserIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // PASSWORD
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.password = iprot.readBinary();
                struct.setPasswordIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, changeLocalUserPassword_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.login != null) {
          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
          oprot.writeBinary(struct.login);
          oprot.writeFieldEnd();
        }
        if (struct.user != null) {
          oprot.writeFieldBegin(USER_FIELD_DESC);
          oprot.writeString(struct.user);
          oprot.writeFieldEnd();
        }
        if (struct.password != null) {
          oprot.writeFieldBegin(PASSWORD_FIELD_DESC);
          oprot.writeBinary(struct.password);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    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 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 {
        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);
        }
        if (struct.isSetUser()) {
          optionals.set(1);
        }
        if (struct.isSetPassword()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetLogin()) {
          oprot.writeBinary(struct.login);
        }
        if (struct.isSetUser()) {
          oprot.writeString(struct.user);
        }
        if (struct.isSetPassword()) {
          oprot.writeBinary(struct.password);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, changeLocalUserPassword_args struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.user = iprot.readString();
          struct.setUserIsSet(true);
        }
        if (incoming.get(2)) {
          struct.password = iprot.readBinary();
          struct.setPasswordIsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("changeLocalUserPassword_result");

    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);

    private static final org.apache.thrift.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

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      OUCH1((short)1, "ouch1"),
      OUCH2((short)2, "ouch2");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // OUCH1
            return OUCH1;
          case 2: // OUCH2
            return OUCH2;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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.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);
    }

    public changeLocalUserPassword_result() {
    }

    public changeLocalUserPassword_result(
      AccumuloException ouch1,
      AccumuloSecurityException ouch2)
    {
      this();
      this.ouch1 = ouch1;
      this.ouch2 = ouch2;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public changeLocalUserPassword_result(changeLocalUserPassword_result other) {
      if (other.isSetOuch1()) {
        this.ouch1 = new AccumuloException(other.ouch1);
      }
      if (other.isSetOuch2()) {
        this.ouch2 = new AccumuloSecurityException(other.ouch2);
      }
    }

    public changeLocalUserPassword_result deepCopy() {
      return new changeLocalUserPassword_result(this);
    }

    @Override
    public void clear() {
      this.ouch1 = null;
      this.ouch2 = null;
    }

    public AccumuloException getOuch1() {
      return this.ouch1;
    }

    public changeLocalUserPassword_result setOuch1(AccumuloException ouch1) {
      this.ouch1 = ouch1;
      return this;
    }

    public void unsetOuch1() {
      this.ouch1 = null;
    }

    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch1() {
      return this.ouch1 != null;
    }

    public void setOuch1IsSet(boolean value) {
      if (!value) {
        this.ouch1 = null;
      }
    }

    public AccumuloSecurityException getOuch2() {
      return this.ouch2;
    }

    public changeLocalUserPassword_result setOuch2(AccumuloSecurityException ouch2) {
      this.ouch2 = ouch2;
      return this;
    }

    public void unsetOuch2() {
      this.ouch2 = null;
    }

    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch2() {
      return this.ouch2 != null;
    }

    public void setOuch2IsSet(boolean value) {
      if (!value) {
        this.ouch2 = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case OUCH1:
        if (value == null) {
          unsetOuch1();
        } else {
          setOuch1((AccumuloException)value);
        }
        break;

      case OUCH2:
        if (value == null) {
          unsetOuch2();
        } else {
          setOuch2((AccumuloSecurityException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case OUCH1:
        return getOuch1();

      case OUCH2:
        return getOuch2();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case OUCH1:
        return isSetOuch1();
      case OUCH2:
        return isSetOuch2();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof changeLocalUserPassword_result)
        return this.equals((changeLocalUserPassword_result)that);
      return false;
    }

    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();
      if (this_present_ouch1 || that_present_ouch1) {
        if (!(this_present_ouch1 && that_present_ouch1))
          return false;
        if (!this.ouch1.equals(that.ouch1))
          return false;
      }

      boolean this_present_ouch2 = true && this.isSetOuch2();
      boolean that_present_ouch2 = true && that.isSetOuch2();
      if (this_present_ouch2 || that_present_ouch2) {
        if (!(this_present_ouch2 && that_present_ouch2))
          return false;
        if (!this.ouch2.equals(that.ouch2))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
      if (isSetOuch1())
        hashCode = hashCode * 8191 + ouch1.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
      if (isSetOuch2())
        hashCode = hashCode * 8191 + ouch2.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(changeLocalUserPassword_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch1()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch2()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("changeLocalUserPassword_result(");
      boolean first = true;

      sb.append("ouch1:");
      if (this.ouch1 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch1);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch2:");
      if (this.ouch2 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch2);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class changeLocalUserPassword_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public changeLocalUserPassword_resultStandardScheme getScheme() {
        return new changeLocalUserPassword_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // OUCH1
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch1 = new AccumuloException();
                struct.ouch1.read(iprot);
                struct.setOuch1IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OUCH2
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch2 = new AccumuloSecurityException();
                struct.ouch2.read(iprot);
                struct.setOuch2IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, changeLocalUserPassword_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.ouch1 != null) {
          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
          struct.ouch1.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch2 != null) {
          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
          struct.ouch2.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class changeLocalUserPassword_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public changeLocalUserPassword_resultTupleScheme getScheme() {
        return new changeLocalUserPassword_resultTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetOuch2()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetOuch1()) {
          struct.ouch1.write(oprot);
        }
        if (struct.isSetOuch2()) {
          struct.ouch2.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, changeLocalUserPassword_result struct) throws org.apache.thrift.TException {
        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);
          struct.setOuch1IsSet(true);
        }
        if (incoming.get(1)) {
          struct.ouch2 = new AccumuloSecurityException();
          struct.ouch2.read(iprot);
          struct.setOuch2IsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("createLocalUser_args");

    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField USER_FIELD_DESC = new org.apache.thrift.protocol.TField("user", org.apache.thrift.protocol.TType.STRING, (short)2);
    private static final org.apache.thrift.protocol.TField PASSWORD_FIELD_DESC = new org.apache.thrift.protocol.TField("password", org.apache.thrift.protocol.TType.STRING, (short)3);

    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 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 {
      LOGIN((short)1, "login"),
      USER((short)2, "user"),
      PASSWORD((short)3, "password");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // LOGIN
            return LOGIN;
          case 2: // USER
            return USER;
          case 3: // PASSWORD
            return PASSWORD;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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 = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(createLocalUser_args.class, metaDataMap);
    }

    public createLocalUser_args() {
    }

    public createLocalUser_args(
      java.nio.ByteBuffer login,
      java.lang.String user,
      java.nio.ByteBuffer password)
    {
      this();
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      this.user = user;
      this.password = org.apache.thrift.TBaseHelper.copyBinary(password);
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public createLocalUser_args(createLocalUser_args other) {
      if (other.isSetLogin()) {
        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
      }
      if (other.isSetUser()) {
        this.user = other.user;
      }
      if (other.isSetPassword()) {
        this.password = org.apache.thrift.TBaseHelper.copyBinary(other.password);
      }
    }

    public createLocalUser_args deepCopy() {
      return new createLocalUser_args(this);
    }

    @Override
    public void clear() {
      this.login = null;
      this.user = null;
      this.password = null;
    }

    public byte[] getLogin() {
      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
      return login == null ? null : login.array();
    }

    public java.nio.ByteBuffer bufferForLogin() {
      return org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    public createLocalUser_args setLogin(byte[] login) {
      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
      return this;
    }

    public createLocalUser_args setLogin(java.nio.ByteBuffer login) {
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      return this;
    }

    public void unsetLogin() {
      this.login = null;
    }

    /** Returns true if field login is set (has been assigned a value) and false otherwise */
    public boolean isSetLogin() {
      return this.login != null;
    }

    public void setLoginIsSet(boolean value) {
      if (!value) {
        this.login = null;
      }
    }

    public java.lang.String getUser() {
      return this.user;
    }

    public createLocalUser_args setUser(java.lang.String user) {
      this.user = user;
      return this;
    }

    public void unsetUser() {
      this.user = null;
    }

    /** Returns true if field user is set (has been assigned a value) and false otherwise */
    public boolean isSetUser() {
      return this.user != null;
    }

    public void setUserIsSet(boolean value) {
      if (!value) {
        this.user = null;
      }
    }

    public byte[] getPassword() {
      setPassword(org.apache.thrift.TBaseHelper.rightSize(password));
      return password == null ? null : password.array();
    }

    public java.nio.ByteBuffer bufferForPassword() {
      return org.apache.thrift.TBaseHelper.copyBinary(password);
    }

    public createLocalUser_args setPassword(byte[] password) {
      this.password = password == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(password.clone());
      return this;
    }

    public createLocalUser_args setPassword(java.nio.ByteBuffer password) {
      this.password = org.apache.thrift.TBaseHelper.copyBinary(password);
      return this;
    }

    public void unsetPassword() {
      this.password = null;
    }

    /** Returns true if field password is set (has been assigned a value) and false otherwise */
    public boolean isSetPassword() {
      return this.password != null;
    }

    public void setPasswordIsSet(boolean value) {
      if (!value) {
        this.password = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case LOGIN:
        if (value == null) {
          unsetLogin();
        } else {
          if (value instanceof byte[]) {
            setLogin((byte[])value);
          } else {
            setLogin((java.nio.ByteBuffer)value);
          }
        }
        break;

      case USER:
        if (value == null) {
          unsetUser();
        } else {
          setUser((java.lang.String)value);
        }
        break;

      case PASSWORD:
        if (value == null) {
          unsetPassword();
        } else {
          if (value instanceof byte[]) {
            setPassword((byte[])value);
          } else {
            setPassword((java.nio.ByteBuffer)value);
          }
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case LOGIN:
        return getLogin();

      case USER:
        return getUser();

      case PASSWORD:
        return getPassword();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case LOGIN:
        return isSetLogin();
      case USER:
        return isSetUser();
      case PASSWORD:
        return isSetPassword();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof createLocalUser_args)
        return this.equals((createLocalUser_args)that);
      return false;
    }

    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();
      if (this_present_login || that_present_login) {
        if (!(this_present_login && that_present_login))
          return false;
        if (!this.login.equals(that.login))
          return false;
      }

      boolean this_present_user = true && this.isSetUser();
      boolean that_present_user = true && that.isSetUser();
      if (this_present_user || that_present_user) {
        if (!(this_present_user && that_present_user))
          return false;
        if (!this.user.equals(that.user))
          return false;
      }

      boolean this_present_password = true && this.isSetPassword();
      boolean that_present_password = true && that.isSetPassword();
      if (this_present_password || that_present_password) {
        if (!(this_present_password && that_present_password))
          return false;
        if (!this.password.equals(that.password))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
      if (isSetLogin())
        hashCode = hashCode * 8191 + login.hashCode();

      hashCode = hashCode * 8191 + ((isSetUser()) ? 131071 : 524287);
      if (isSetUser())
        hashCode = hashCode * 8191 + user.hashCode();

      hashCode = hashCode * 8191 + ((isSetPassword()) ? 131071 : 524287);
      if (isSetPassword())
        hashCode = hashCode * 8191 + password.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(createLocalUser_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLogin()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetUser()).compareTo(other.isSetUser());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetUser()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.user, other.user);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetPassword()).compareTo(other.isSetPassword());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetPassword()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.password, other.password);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("createLocalUser_args(");
      boolean first = true;

      sb.append("login:");
      if (this.login == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.login, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("user:");
      if (this.user == null) {
        sb.append("null");
      } else {
        sb.append(this.user);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("password:");
      if (this.password == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.password, sb);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class createLocalUser_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public createLocalUser_argsStandardScheme getScheme() {
        return new createLocalUser_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // LOGIN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.login = iprot.readBinary();
                struct.setLoginIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // USER
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.user = iprot.readString();
                struct.setUserIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // PASSWORD
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.password = iprot.readBinary();
                struct.setPasswordIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, createLocalUser_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.login != null) {
          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
          oprot.writeBinary(struct.login);
          oprot.writeFieldEnd();
        }
        if (struct.user != null) {
          oprot.writeFieldBegin(USER_FIELD_DESC);
          oprot.writeString(struct.user);
          oprot.writeFieldEnd();
        }
        if (struct.password != null) {
          oprot.writeFieldBegin(PASSWORD_FIELD_DESC);
          oprot.writeBinary(struct.password);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    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 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 {
        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);
        }
        if (struct.isSetUser()) {
          optionals.set(1);
        }
        if (struct.isSetPassword()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetLogin()) {
          oprot.writeBinary(struct.login);
        }
        if (struct.isSetUser()) {
          oprot.writeString(struct.user);
        }
        if (struct.isSetPassword()) {
          oprot.writeBinary(struct.password);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, createLocalUser_args struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.user = iprot.readString();
          struct.setUserIsSet(true);
        }
        if (incoming.get(2)) {
          struct.password = iprot.readBinary();
          struct.setPasswordIsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("createLocalUser_result");

    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);

    private static final org.apache.thrift.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

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      OUCH1((short)1, "ouch1"),
      OUCH2((short)2, "ouch2");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // OUCH1
            return OUCH1;
          case 2: // OUCH2
            return OUCH2;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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.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);
    }

    public createLocalUser_result() {
    }

    public createLocalUser_result(
      AccumuloException ouch1,
      AccumuloSecurityException ouch2)
    {
      this();
      this.ouch1 = ouch1;
      this.ouch2 = ouch2;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public createLocalUser_result(createLocalUser_result other) {
      if (other.isSetOuch1()) {
        this.ouch1 = new AccumuloException(other.ouch1);
      }
      if (other.isSetOuch2()) {
        this.ouch2 = new AccumuloSecurityException(other.ouch2);
      }
    }

    public createLocalUser_result deepCopy() {
      return new createLocalUser_result(this);
    }

    @Override
    public void clear() {
      this.ouch1 = null;
      this.ouch2 = null;
    }

    public AccumuloException getOuch1() {
      return this.ouch1;
    }

    public createLocalUser_result setOuch1(AccumuloException ouch1) {
      this.ouch1 = ouch1;
      return this;
    }

    public void unsetOuch1() {
      this.ouch1 = null;
    }

    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch1() {
      return this.ouch1 != null;
    }

    public void setOuch1IsSet(boolean value) {
      if (!value) {
        this.ouch1 = null;
      }
    }

    public AccumuloSecurityException getOuch2() {
      return this.ouch2;
    }

    public createLocalUser_result setOuch2(AccumuloSecurityException ouch2) {
      this.ouch2 = ouch2;
      return this;
    }

    public void unsetOuch2() {
      this.ouch2 = null;
    }

    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch2() {
      return this.ouch2 != null;
    }

    public void setOuch2IsSet(boolean value) {
      if (!value) {
        this.ouch2 = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case OUCH1:
        if (value == null) {
          unsetOuch1();
        } else {
          setOuch1((AccumuloException)value);
        }
        break;

      case OUCH2:
        if (value == null) {
          unsetOuch2();
        } else {
          setOuch2((AccumuloSecurityException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case OUCH1:
        return getOuch1();

      case OUCH2:
        return getOuch2();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case OUCH1:
        return isSetOuch1();
      case OUCH2:
        return isSetOuch2();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof createLocalUser_result)
        return this.equals((createLocalUser_result)that);
      return false;
    }

    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();
      if (this_present_ouch1 || that_present_ouch1) {
        if (!(this_present_ouch1 && that_present_ouch1))
          return false;
        if (!this.ouch1.equals(that.ouch1))
          return false;
      }

      boolean this_present_ouch2 = true && this.isSetOuch2();
      boolean that_present_ouch2 = true && that.isSetOuch2();
      if (this_present_ouch2 || that_present_ouch2) {
        if (!(this_present_ouch2 && that_present_ouch2))
          return false;
        if (!this.ouch2.equals(that.ouch2))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
      if (isSetOuch1())
        hashCode = hashCode * 8191 + ouch1.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
      if (isSetOuch2())
        hashCode = hashCode * 8191 + ouch2.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(createLocalUser_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch1()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch2()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("createLocalUser_result(");
      boolean first = true;

      sb.append("ouch1:");
      if (this.ouch1 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch1);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch2:");
      if (this.ouch2 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch2);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class createLocalUser_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public createLocalUser_resultStandardScheme getScheme() {
        return new createLocalUser_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // OUCH1
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch1 = new AccumuloException();
                struct.ouch1.read(iprot);
                struct.setOuch1IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OUCH2
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch2 = new AccumuloSecurityException();
                struct.ouch2.read(iprot);
                struct.setOuch2IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, createLocalUser_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.ouch1 != null) {
          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
          struct.ouch1.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch2 != null) {
          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
          struct.ouch2.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class createLocalUser_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public createLocalUser_resultTupleScheme getScheme() {
        return new createLocalUser_resultTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetOuch2()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetOuch1()) {
          struct.ouch1.write(oprot);
        }
        if (struct.isSetOuch2()) {
          struct.ouch2.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, createLocalUser_result struct) throws org.apache.thrift.TException {
        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);
          struct.setOuch1IsSet(true);
        }
        if (incoming.get(1)) {
          struct.ouch2 = new AccumuloSecurityException();
          struct.ouch2.read(iprot);
          struct.setOuch2IsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("dropLocalUser_args");

    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField USER_FIELD_DESC = new org.apache.thrift.protocol.TField("user", org.apache.thrift.protocol.TType.STRING, (short)2);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new dropLocalUser_argsStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new dropLocalUser_argsTupleSchemeFactory();

    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 java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // LOGIN
            return LOGIN;
          case 2: // USER
            return USER;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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 = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(dropLocalUser_args.class, metaDataMap);
    }

    public dropLocalUser_args() {
    }

    public dropLocalUser_args(
      java.nio.ByteBuffer login,
      java.lang.String user)
    {
      this();
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      this.user = user;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public dropLocalUser_args(dropLocalUser_args other) {
      if (other.isSetLogin()) {
        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
      }
      if (other.isSetUser()) {
        this.user = other.user;
      }
    }

    public dropLocalUser_args deepCopy() {
      return new dropLocalUser_args(this);
    }

    @Override
    public void clear() {
      this.login = null;
      this.user = null;
    }

    public byte[] getLogin() {
      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
      return login == null ? null : login.array();
    }

    public java.nio.ByteBuffer bufferForLogin() {
      return org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    public dropLocalUser_args setLogin(byte[] login) {
      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
      return this;
    }

    public dropLocalUser_args setLogin(java.nio.ByteBuffer login) {
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      return this;
    }

    public void unsetLogin() {
      this.login = null;
    }

    /** Returns true if field login is set (has been assigned a value) and false otherwise */
    public boolean isSetLogin() {
      return this.login != null;
    }

    public void setLoginIsSet(boolean value) {
      if (!value) {
        this.login = null;
      }
    }

    public java.lang.String getUser() {
      return this.user;
    }

    public dropLocalUser_args setUser(java.lang.String user) {
      this.user = user;
      return this;
    }

    public void unsetUser() {
      this.user = null;
    }

    /** Returns true if field user is set (has been assigned a value) and false otherwise */
    public boolean isSetUser() {
      return this.user != null;
    }

    public void setUserIsSet(boolean value) {
      if (!value) {
        this.user = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case LOGIN:
        if (value == null) {
          unsetLogin();
        } else {
          if (value instanceof byte[]) {
            setLogin((byte[])value);
          } else {
            setLogin((java.nio.ByteBuffer)value);
          }
        }
        break;

      case USER:
        if (value == null) {
          unsetUser();
        } else {
          setUser((java.lang.String)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case LOGIN:
        return getLogin();

      case USER:
        return getUser();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case LOGIN:
        return isSetLogin();
      case USER:
        return isSetUser();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof dropLocalUser_args)
        return this.equals((dropLocalUser_args)that);
      return false;
    }

    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();
      if (this_present_login || that_present_login) {
        if (!(this_present_login && that_present_login))
          return false;
        if (!this.login.equals(that.login))
          return false;
      }

      boolean this_present_user = true && this.isSetUser();
      boolean that_present_user = true && that.isSetUser();
      if (this_present_user || that_present_user) {
        if (!(this_present_user && that_present_user))
          return false;
        if (!this.user.equals(that.user))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
      if (isSetLogin())
        hashCode = hashCode * 8191 + login.hashCode();

      hashCode = hashCode * 8191 + ((isSetUser()) ? 131071 : 524287);
      if (isSetUser())
        hashCode = hashCode * 8191 + user.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(dropLocalUser_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLogin()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetUser()).compareTo(other.isSetUser());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetUser()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.user, other.user);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("dropLocalUser_args(");
      boolean first = true;

      sb.append("login:");
      if (this.login == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.login, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("user:");
      if (this.user == null) {
        sb.append("null");
      } else {
        sb.append(this.user);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class dropLocalUser_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public dropLocalUser_argsStandardScheme getScheme() {
        return new dropLocalUser_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // LOGIN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.login = iprot.readBinary();
                struct.setLoginIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // USER
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.user = iprot.readString();
                struct.setUserIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, dropLocalUser_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.login != null) {
          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
          oprot.writeBinary(struct.login);
          oprot.writeFieldEnd();
        }
        if (struct.user != null) {
          oprot.writeFieldBegin(USER_FIELD_DESC);
          oprot.writeString(struct.user);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    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 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 {
        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);
        }
        if (struct.isSetUser()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetLogin()) {
          oprot.writeBinary(struct.login);
        }
        if (struct.isSetUser()) {
          oprot.writeString(struct.user);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, dropLocalUser_args struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.user = iprot.readString();
          struct.setUserIsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("dropLocalUser_result");

    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);

    private static final org.apache.thrift.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

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      OUCH1((short)1, "ouch1"),
      OUCH2((short)2, "ouch2");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // OUCH1
            return OUCH1;
          case 2: // OUCH2
            return OUCH2;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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.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);
    }

    public dropLocalUser_result() {
    }

    public dropLocalUser_result(
      AccumuloException ouch1,
      AccumuloSecurityException ouch2)
    {
      this();
      this.ouch1 = ouch1;
      this.ouch2 = ouch2;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public dropLocalUser_result(dropLocalUser_result other) {
      if (other.isSetOuch1()) {
        this.ouch1 = new AccumuloException(other.ouch1);
      }
      if (other.isSetOuch2()) {
        this.ouch2 = new AccumuloSecurityException(other.ouch2);
      }
    }

    public dropLocalUser_result deepCopy() {
      return new dropLocalUser_result(this);
    }

    @Override
    public void clear() {
      this.ouch1 = null;
      this.ouch2 = null;
    }

    public AccumuloException getOuch1() {
      return this.ouch1;
    }

    public dropLocalUser_result setOuch1(AccumuloException ouch1) {
      this.ouch1 = ouch1;
      return this;
    }

    public void unsetOuch1() {
      this.ouch1 = null;
    }

    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch1() {
      return this.ouch1 != null;
    }

    public void setOuch1IsSet(boolean value) {
      if (!value) {
        this.ouch1 = null;
      }
    }

    public AccumuloSecurityException getOuch2() {
      return this.ouch2;
    }

    public dropLocalUser_result setOuch2(AccumuloSecurityException ouch2) {
      this.ouch2 = ouch2;
      return this;
    }

    public void unsetOuch2() {
      this.ouch2 = null;
    }

    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch2() {
      return this.ouch2 != null;
    }

    public void setOuch2IsSet(boolean value) {
      if (!value) {
        this.ouch2 = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case OUCH1:
        if (value == null) {
          unsetOuch1();
        } else {
          setOuch1((AccumuloException)value);
        }
        break;

      case OUCH2:
        if (value == null) {
          unsetOuch2();
        } else {
          setOuch2((AccumuloSecurityException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case OUCH1:
        return getOuch1();

      case OUCH2:
        return getOuch2();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case OUCH1:
        return isSetOuch1();
      case OUCH2:
        return isSetOuch2();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof dropLocalUser_result)
        return this.equals((dropLocalUser_result)that);
      return false;
    }

    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();
      if (this_present_ouch1 || that_present_ouch1) {
        if (!(this_present_ouch1 && that_present_ouch1))
          return false;
        if (!this.ouch1.equals(that.ouch1))
          return false;
      }

      boolean this_present_ouch2 = true && this.isSetOuch2();
      boolean that_present_ouch2 = true && that.isSetOuch2();
      if (this_present_ouch2 || that_present_ouch2) {
        if (!(this_present_ouch2 && that_present_ouch2))
          return false;
        if (!this.ouch2.equals(that.ouch2))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
      if (isSetOuch1())
        hashCode = hashCode * 8191 + ouch1.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
      if (isSetOuch2())
        hashCode = hashCode * 8191 + ouch2.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(dropLocalUser_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch1()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch2()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("dropLocalUser_result(");
      boolean first = true;

      sb.append("ouch1:");
      if (this.ouch1 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch1);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch2:");
      if (this.ouch2 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch2);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class dropLocalUser_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public dropLocalUser_resultStandardScheme getScheme() {
        return new dropLocalUser_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // OUCH1
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch1 = new AccumuloException();
                struct.ouch1.read(iprot);
                struct.setOuch1IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OUCH2
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch2 = new AccumuloSecurityException();
                struct.ouch2.read(iprot);
                struct.setOuch2IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, dropLocalUser_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.ouch1 != null) {
          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
          struct.ouch1.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch2 != null) {
          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
          struct.ouch2.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class dropLocalUser_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public dropLocalUser_resultTupleScheme getScheme() {
        return new dropLocalUser_resultTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetOuch2()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetOuch1()) {
          struct.ouch1.write(oprot);
        }
        if (struct.isSetOuch2()) {
          struct.ouch2.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, dropLocalUser_result struct) throws org.apache.thrift.TException {
        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);
          struct.setOuch1IsSet(true);
        }
        if (incoming.get(1)) {
          struct.ouch2 = new AccumuloSecurityException();
          struct.ouch2.read(iprot);
          struct.setOuch2IsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getUserAuthorizations_args");

    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField USER_FIELD_DESC = new org.apache.thrift.protocol.TField("user", org.apache.thrift.protocol.TType.STRING, (short)2);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new getUserAuthorizations_argsStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new getUserAuthorizations_argsTupleSchemeFactory();

    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 java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // LOGIN
            return LOGIN;
          case 2: // USER
            return USER;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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 = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getUserAuthorizations_args.class, metaDataMap);
    }

    public getUserAuthorizations_args() {
    }

    public getUserAuthorizations_args(
      java.nio.ByteBuffer login,
      java.lang.String user)
    {
      this();
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      this.user = user;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getUserAuthorizations_args(getUserAuthorizations_args other) {
      if (other.isSetLogin()) {
        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
      }
      if (other.isSetUser()) {
        this.user = other.user;
      }
    }

    public getUserAuthorizations_args deepCopy() {
      return new getUserAuthorizations_args(this);
    }

    @Override
    public void clear() {
      this.login = null;
      this.user = null;
    }

    public byte[] getLogin() {
      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
      return login == null ? null : login.array();
    }

    public java.nio.ByteBuffer bufferForLogin() {
      return org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    public getUserAuthorizations_args setLogin(byte[] login) {
      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
      return this;
    }

    public getUserAuthorizations_args setLogin(java.nio.ByteBuffer login) {
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      return this;
    }

    public void unsetLogin() {
      this.login = null;
    }

    /** Returns true if field login is set (has been assigned a value) and false otherwise */
    public boolean isSetLogin() {
      return this.login != null;
    }

    public void setLoginIsSet(boolean value) {
      if (!value) {
        this.login = null;
      }
    }

    public java.lang.String getUser() {
      return this.user;
    }

    public getUserAuthorizations_args setUser(java.lang.String user) {
      this.user = user;
      return this;
    }

    public void unsetUser() {
      this.user = null;
    }

    /** Returns true if field user is set (has been assigned a value) and false otherwise */
    public boolean isSetUser() {
      return this.user != null;
    }

    public void setUserIsSet(boolean value) {
      if (!value) {
        this.user = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case LOGIN:
        if (value == null) {
          unsetLogin();
        } else {
          if (value instanceof byte[]) {
            setLogin((byte[])value);
          } else {
            setLogin((java.nio.ByteBuffer)value);
          }
        }
        break;

      case USER:
        if (value == null) {
          unsetUser();
        } else {
          setUser((java.lang.String)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case LOGIN:
        return getLogin();

      case USER:
        return getUser();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case LOGIN:
        return isSetLogin();
      case USER:
        return isSetUser();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof getUserAuthorizations_args)
        return this.equals((getUserAuthorizations_args)that);
      return false;
    }

    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();
      if (this_present_login || that_present_login) {
        if (!(this_present_login && that_present_login))
          return false;
        if (!this.login.equals(that.login))
          return false;
      }

      boolean this_present_user = true && this.isSetUser();
      boolean that_present_user = true && that.isSetUser();
      if (this_present_user || that_present_user) {
        if (!(this_present_user && that_present_user))
          return false;
        if (!this.user.equals(that.user))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
      if (isSetLogin())
        hashCode = hashCode * 8191 + login.hashCode();

      hashCode = hashCode * 8191 + ((isSetUser()) ? 131071 : 524287);
      if (isSetUser())
        hashCode = hashCode * 8191 + user.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(getUserAuthorizations_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLogin()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetUser()).compareTo(other.isSetUser());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetUser()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.user, other.user);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("getUserAuthorizations_args(");
      boolean first = true;

      sb.append("login:");
      if (this.login == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.login, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("user:");
      if (this.user == null) {
        sb.append("null");
      } else {
        sb.append(this.user);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class getUserAuthorizations_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getUserAuthorizations_argsStandardScheme getScheme() {
        return new getUserAuthorizations_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // LOGIN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.login = iprot.readBinary();
                struct.setLoginIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // USER
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.user = iprot.readString();
                struct.setUserIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getUserAuthorizations_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.login != null) {
          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
          oprot.writeBinary(struct.login);
          oprot.writeFieldEnd();
        }
        if (struct.user != null) {
          oprot.writeFieldBegin(USER_FIELD_DESC);
          oprot.writeString(struct.user);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    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 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 {
        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);
        }
        if (struct.isSetUser()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetLogin()) {
          oprot.writeBinary(struct.login);
        }
        if (struct.isSetUser()) {
          oprot.writeString(struct.user);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getUserAuthorizations_args struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.user = iprot.readString();
          struct.setUserIsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getUserAuthorizations_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.LIST, (short)0);
    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);

    private static final 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 java.util.List<java.nio.ByteBuffer> success; // required
    public AccumuloException ouch1; // required
    public AccumuloSecurityException ouch2; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      OUCH1((short)1, "ouch1"),
      OUCH2((short)2, "ouch2");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // OUCH1
            return OUCH1;
          case 2: // OUCH2
            return OUCH2;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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.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);
    }

    public getUserAuthorizations_result() {
    }

    public getUserAuthorizations_result(
      java.util.List<java.nio.ByteBuffer> success,
      AccumuloException ouch1,
      AccumuloSecurityException ouch2)
    {
      this();
      this.success = success;
      this.ouch1 = ouch1;
      this.ouch2 = ouch2;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getUserAuthorizations_result(getUserAuthorizations_result other) {
      if (other.isSetSuccess()) {
        java.util.List<java.nio.ByteBuffer> __this__success = new java.util.ArrayList<java.nio.ByteBuffer>(other.success);
        this.success = __this__success;
      }
      if (other.isSetOuch1()) {
        this.ouch1 = new AccumuloException(other.ouch1);
      }
      if (other.isSetOuch2()) {
        this.ouch2 = new AccumuloSecurityException(other.ouch2);
      }
    }

    public getUserAuthorizations_result deepCopy() {
      return new getUserAuthorizations_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ouch1 = null;
      this.ouch2 = null;
    }

    public int getSuccessSize() {
      return (this.success == null) ? 0 : this.success.size();
    }

    public java.util.Iterator<java.nio.ByteBuffer> getSuccessIterator() {
      return (this.success == null) ? null : this.success.iterator();
    }

    public void addToSuccess(java.nio.ByteBuffer elem) {
      if (this.success == null) {
        this.success = new java.util.ArrayList<java.nio.ByteBuffer>();
      }
      this.success.add(elem);
    }

    public java.util.List<java.nio.ByteBuffer> getSuccess() {
      return this.success;
    }

    public getUserAuthorizations_result setSuccess(java.util.List<java.nio.ByteBuffer> success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return this.success != null;
    }

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public AccumuloException getOuch1() {
      return this.ouch1;
    }

    public getUserAuthorizations_result setOuch1(AccumuloException ouch1) {
      this.ouch1 = ouch1;
      return this;
    }

    public void unsetOuch1() {
      this.ouch1 = null;
    }

    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch1() {
      return this.ouch1 != null;
    }

    public void setOuch1IsSet(boolean value) {
      if (!value) {
        this.ouch1 = null;
      }
    }

    public AccumuloSecurityException getOuch2() {
      return this.ouch2;
    }

    public getUserAuthorizations_result setOuch2(AccumuloSecurityException ouch2) {
      this.ouch2 = ouch2;
      return this;
    }

    public void unsetOuch2() {
      this.ouch2 = null;
    }

    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch2() {
      return this.ouch2 != null;
    }

    public void setOuch2IsSet(boolean value) {
      if (!value) {
        this.ouch2 = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.util.List<java.nio.ByteBuffer>)value);
        }
        break;

      case OUCH1:
        if (value == null) {
          unsetOuch1();
        } else {
          setOuch1((AccumuloException)value);
        }
        break;

      case OUCH2:
        if (value == null) {
          unsetOuch2();
        } else {
          setOuch2((AccumuloSecurityException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case OUCH1:
        return getOuch1();

      case OUCH2:
        return getOuch2();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case OUCH1:
        return isSetOuch1();
      case OUCH2:
        return isSetOuch2();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof getUserAuthorizations_result)
        return this.equals((getUserAuthorizations_result)that);
      return false;
    }

    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();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ouch1 = true && this.isSetOuch1();
      boolean that_present_ouch1 = true && that.isSetOuch1();
      if (this_present_ouch1 || that_present_ouch1) {
        if (!(this_present_ouch1 && that_present_ouch1))
          return false;
        if (!this.ouch1.equals(that.ouch1))
          return false;
      }

      boolean this_present_ouch2 = true && this.isSetOuch2();
      boolean that_present_ouch2 = true && that.isSetOuch2();
      if (this_present_ouch2 || that_present_ouch2) {
        if (!(this_present_ouch2 && that_present_ouch2))
          return false;
        if (!this.ouch2.equals(that.ouch2))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
      if (isSetSuccess())
        hashCode = hashCode * 8191 + success.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
      if (isSetOuch1())
        hashCode = hashCode * 8191 + ouch1.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
      if (isSetOuch2())
        hashCode = hashCode * 8191 + ouch2.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(getUserAuthorizations_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch1()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch2()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("getUserAuthorizations_result(");
      boolean first = true;

      sb.append("success:");
      if (this.success == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.success, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch1:");
      if (this.ouch1 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch1);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch2:");
      if (this.ouch2 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch2);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class getUserAuthorizations_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getUserAuthorizations_resultStandardScheme getScheme() {
        return new getUserAuthorizations_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
                {
                  org.apache.thrift.protocol.TList _list426 = iprot.readListBegin();
                  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();
                    struct.success.add(_elem427);
                  }
                  iprot.readListEnd();
                }
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // OUCH1
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch1 = new AccumuloException();
                struct.ouch1.read(iprot);
                struct.setOuch1IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OUCH2
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch2 = new AccumuloSecurityException();
                struct.ouch2.read(iprot);
                struct.setOuch2IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getUserAuthorizations_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRING, struct.success.size()));
            for (java.nio.ByteBuffer _iter429 : struct.success)
            {
              oprot.writeBinary(_iter429);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.ouch1 != null) {
          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
          struct.ouch1.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch2 != null) {
          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
          struct.ouch2.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getUserAuthorizations_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getUserAuthorizations_resultTupleScheme getScheme() {
        return new getUserAuthorizations_resultTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetOuch1()) {
          optionals.set(1);
        }
        if (struct.isSetOuch2()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetSuccess()) {
          {
            oprot.writeI32(struct.success.size());
            for (java.nio.ByteBuffer _iter430 : struct.success)
            {
              oprot.writeBinary(_iter430);
            }
          }
        }
        if (struct.isSetOuch1()) {
          struct.ouch1.write(oprot);
        }
        if (struct.isSetOuch2()) {
          struct.ouch2.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getUserAuthorizations_result struct) throws org.apache.thrift.TException {
        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 java.util.ArrayList<java.nio.ByteBuffer>(_list431.size);
            java.nio.ByteBuffer _elem432;
            for (int _i433 = 0; _i433 < _list431.size; ++_i433)
            {
              _elem432 = iprot.readBinary();
              struct.success.add(_elem432);
            }
          }
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ouch1 = new AccumuloException();
          struct.ouch1.read(iprot);
          struct.setOuch1IsSet(true);
        }
        if (incoming.get(2)) {
          struct.ouch2 = new AccumuloSecurityException();
          struct.ouch2.read(iprot);
          struct.setOuch2IsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("grantSystemPermission_args");

    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField USER_FIELD_DESC = new org.apache.thrift.protocol.TField("user", org.apache.thrift.protocol.TType.STRING, (short)2);
    private static final org.apache.thrift.protocol.TField PERM_FIELD_DESC = new org.apache.thrift.protocol.TField("perm", org.apache.thrift.protocol.TType.I32, (short)3);

    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 java.nio.ByteBuffer login; // required
    public java.lang.String user; // required
    /**
     * 
     * @see SystemPermission
     */
    public SystemPermission perm; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      LOGIN((short)1, "login"),
      USER((short)2, "user"),
      /**
       * 
       * @see SystemPermission
       */
      PERM((short)3, "perm");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // LOGIN
            return LOGIN;
          case 2: // USER
            return USER;
          case 3: // PERM
            return PERM;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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 = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(grantSystemPermission_args.class, metaDataMap);
    }

    public grantSystemPermission_args() {
    }

    public grantSystemPermission_args(
      java.nio.ByteBuffer login,
      java.lang.String user,
      SystemPermission perm)
    {
      this();
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      this.user = user;
      this.perm = perm;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public grantSystemPermission_args(grantSystemPermission_args other) {
      if (other.isSetLogin()) {
        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
      }
      if (other.isSetUser()) {
        this.user = other.user;
      }
      if (other.isSetPerm()) {
        this.perm = other.perm;
      }
    }

    public grantSystemPermission_args deepCopy() {
      return new grantSystemPermission_args(this);
    }

    @Override
    public void clear() {
      this.login = null;
      this.user = null;
      this.perm = null;
    }

    public byte[] getLogin() {
      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
      return login == null ? null : login.array();
    }

    public java.nio.ByteBuffer bufferForLogin() {
      return org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    public grantSystemPermission_args setLogin(byte[] login) {
      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
      return this;
    }

    public grantSystemPermission_args setLogin(java.nio.ByteBuffer login) {
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      return this;
    }

    public void unsetLogin() {
      this.login = null;
    }

    /** Returns true if field login is set (has been assigned a value) and false otherwise */
    public boolean isSetLogin() {
      return this.login != null;
    }

    public void setLoginIsSet(boolean value) {
      if (!value) {
        this.login = null;
      }
    }

    public java.lang.String getUser() {
      return this.user;
    }

    public grantSystemPermission_args setUser(java.lang.String user) {
      this.user = user;
      return this;
    }

    public void unsetUser() {
      this.user = null;
    }

    /** Returns true if field user is set (has been assigned a value) and false otherwise */
    public boolean isSetUser() {
      return this.user != null;
    }

    public void setUserIsSet(boolean value) {
      if (!value) {
        this.user = null;
      }
    }

    /**
     * 
     * @see SystemPermission
     */
    public SystemPermission getPerm() {
      return this.perm;
    }

    /**
     * 
     * @see SystemPermission
     */
    public grantSystemPermission_args setPerm(SystemPermission perm) {
      this.perm = perm;
      return this;
    }

    public void unsetPerm() {
      this.perm = null;
    }

    /** Returns true if field perm is set (has been assigned a value) and false otherwise */
    public boolean isSetPerm() {
      return this.perm != null;
    }

    public void setPermIsSet(boolean value) {
      if (!value) {
        this.perm = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case LOGIN:
        if (value == null) {
          unsetLogin();
        } else {
          if (value instanceof byte[]) {
            setLogin((byte[])value);
          } else {
            setLogin((java.nio.ByteBuffer)value);
          }
        }
        break;

      case USER:
        if (value == null) {
          unsetUser();
        } else {
          setUser((java.lang.String)value);
        }
        break;

      case PERM:
        if (value == null) {
          unsetPerm();
        } else {
          setPerm((SystemPermission)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case LOGIN:
        return getLogin();

      case USER:
        return getUser();

      case PERM:
        return getPerm();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case LOGIN:
        return isSetLogin();
      case USER:
        return isSetUser();
      case PERM:
        return isSetPerm();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof grantSystemPermission_args)
        return this.equals((grantSystemPermission_args)that);
      return false;
    }

    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();
      if (this_present_login || that_present_login) {
        if (!(this_present_login && that_present_login))
          return false;
        if (!this.login.equals(that.login))
          return false;
      }

      boolean this_present_user = true && this.isSetUser();
      boolean that_present_user = true && that.isSetUser();
      if (this_present_user || that_present_user) {
        if (!(this_present_user && that_present_user))
          return false;
        if (!this.user.equals(that.user))
          return false;
      }

      boolean this_present_perm = true && this.isSetPerm();
      boolean that_present_perm = true && that.isSetPerm();
      if (this_present_perm || that_present_perm) {
        if (!(this_present_perm && that_present_perm))
          return false;
        if (!this.perm.equals(that.perm))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
      if (isSetLogin())
        hashCode = hashCode * 8191 + login.hashCode();

      hashCode = hashCode * 8191 + ((isSetUser()) ? 131071 : 524287);
      if (isSetUser())
        hashCode = hashCode * 8191 + user.hashCode();

      hashCode = hashCode * 8191 + ((isSetPerm()) ? 131071 : 524287);
      if (isSetPerm())
        hashCode = hashCode * 8191 + perm.getValue();

      return hashCode;
    }

    @Override
    public int compareTo(grantSystemPermission_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLogin()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetUser()).compareTo(other.isSetUser());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetUser()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.user, other.user);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetPerm()).compareTo(other.isSetPerm());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetPerm()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.perm, other.perm);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("grantSystemPermission_args(");
      boolean first = true;

      sb.append("login:");
      if (this.login == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.login, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("user:");
      if (this.user == null) {
        sb.append("null");
      } else {
        sb.append(this.user);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("perm:");
      if (this.perm == null) {
        sb.append("null");
      } else {
        sb.append(this.perm);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class grantSystemPermission_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public grantSystemPermission_argsStandardScheme getScheme() {
        return new grantSystemPermission_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // LOGIN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.login = iprot.readBinary();
                struct.setLoginIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // USER
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.user = iprot.readString();
                struct.setUserIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // PERM
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.perm = org.apache.accumulo.proxy.thrift.SystemPermission.findByValue(iprot.readI32());
                struct.setPermIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, grantSystemPermission_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.login != null) {
          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
          oprot.writeBinary(struct.login);
          oprot.writeFieldEnd();
        }
        if (struct.user != null) {
          oprot.writeFieldBegin(USER_FIELD_DESC);
          oprot.writeString(struct.user);
          oprot.writeFieldEnd();
        }
        if (struct.perm != null) {
          oprot.writeFieldBegin(PERM_FIELD_DESC);
          oprot.writeI32(struct.perm.getValue());
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    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 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 {
        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);
        }
        if (struct.isSetUser()) {
          optionals.set(1);
        }
        if (struct.isSetPerm()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetLogin()) {
          oprot.writeBinary(struct.login);
        }
        if (struct.isSetUser()) {
          oprot.writeString(struct.user);
        }
        if (struct.isSetPerm()) {
          oprot.writeI32(struct.perm.getValue());
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, grantSystemPermission_args struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.user = iprot.readString();
          struct.setUserIsSet(true);
        }
        if (incoming.get(2)) {
          struct.perm = org.apache.accumulo.proxy.thrift.SystemPermission.findByValue(iprot.readI32());
          struct.setPermIsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("grantSystemPermission_result");

    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);

    private static final org.apache.thrift.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

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      OUCH1((short)1, "ouch1"),
      OUCH2((short)2, "ouch2");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // OUCH1
            return OUCH1;
          case 2: // OUCH2
            return OUCH2;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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.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);
    }

    public grantSystemPermission_result() {
    }

    public grantSystemPermission_result(
      AccumuloException ouch1,
      AccumuloSecurityException ouch2)
    {
      this();
      this.ouch1 = ouch1;
      this.ouch2 = ouch2;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public grantSystemPermission_result(grantSystemPermission_result other) {
      if (other.isSetOuch1()) {
        this.ouch1 = new AccumuloException(other.ouch1);
      }
      if (other.isSetOuch2()) {
        this.ouch2 = new AccumuloSecurityException(other.ouch2);
      }
    }

    public grantSystemPermission_result deepCopy() {
      return new grantSystemPermission_result(this);
    }

    @Override
    public void clear() {
      this.ouch1 = null;
      this.ouch2 = null;
    }

    public AccumuloException getOuch1() {
      return this.ouch1;
    }

    public grantSystemPermission_result setOuch1(AccumuloException ouch1) {
      this.ouch1 = ouch1;
      return this;
    }

    public void unsetOuch1() {
      this.ouch1 = null;
    }

    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch1() {
      return this.ouch1 != null;
    }

    public void setOuch1IsSet(boolean value) {
      if (!value) {
        this.ouch1 = null;
      }
    }

    public AccumuloSecurityException getOuch2() {
      return this.ouch2;
    }

    public grantSystemPermission_result setOuch2(AccumuloSecurityException ouch2) {
      this.ouch2 = ouch2;
      return this;
    }

    public void unsetOuch2() {
      this.ouch2 = null;
    }

    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch2() {
      return this.ouch2 != null;
    }

    public void setOuch2IsSet(boolean value) {
      if (!value) {
        this.ouch2 = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case OUCH1:
        if (value == null) {
          unsetOuch1();
        } else {
          setOuch1((AccumuloException)value);
        }
        break;

      case OUCH2:
        if (value == null) {
          unsetOuch2();
        } else {
          setOuch2((AccumuloSecurityException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case OUCH1:
        return getOuch1();

      case OUCH2:
        return getOuch2();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case OUCH1:
        return isSetOuch1();
      case OUCH2:
        return isSetOuch2();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof grantSystemPermission_result)
        return this.equals((grantSystemPermission_result)that);
      return false;
    }

    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();
      if (this_present_ouch1 || that_present_ouch1) {
        if (!(this_present_ouch1 && that_present_ouch1))
          return false;
        if (!this.ouch1.equals(that.ouch1))
          return false;
      }

      boolean this_present_ouch2 = true && this.isSetOuch2();
      boolean that_present_ouch2 = true && that.isSetOuch2();
      if (this_present_ouch2 || that_present_ouch2) {
        if (!(this_present_ouch2 && that_present_ouch2))
          return false;
        if (!this.ouch2.equals(that.ouch2))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
      if (isSetOuch1())
        hashCode = hashCode * 8191 + ouch1.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
      if (isSetOuch2())
        hashCode = hashCode * 8191 + ouch2.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(grantSystemPermission_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch1()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch2()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("grantSystemPermission_result(");
      boolean first = true;

      sb.append("ouch1:");
      if (this.ouch1 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch1);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch2:");
      if (this.ouch2 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch2);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class grantSystemPermission_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public grantSystemPermission_resultStandardScheme getScheme() {
        return new grantSystemPermission_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // OUCH1
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch1 = new AccumuloException();
                struct.ouch1.read(iprot);
                struct.setOuch1IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OUCH2
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch2 = new AccumuloSecurityException();
                struct.ouch2.read(iprot);
                struct.setOuch2IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, grantSystemPermission_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.ouch1 != null) {
          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
          struct.ouch1.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch2 != null) {
          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
          struct.ouch2.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class grantSystemPermission_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public grantSystemPermission_resultTupleScheme getScheme() {
        return new grantSystemPermission_resultTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetOuch2()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetOuch1()) {
          struct.ouch1.write(oprot);
        }
        if (struct.isSetOuch2()) {
          struct.ouch2.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, grantSystemPermission_result struct) throws org.apache.thrift.TException {
        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);
          struct.setOuch1IsSet(true);
        }
        if (incoming.get(1)) {
          struct.ouch2 = new AccumuloSecurityException();
          struct.ouch2.read(iprot);
          struct.setOuch2IsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("grantTablePermission_args");

    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField USER_FIELD_DESC = new org.apache.thrift.protocol.TField("user", org.apache.thrift.protocol.TType.STRING, (short)2);
    private static final org.apache.thrift.protocol.TField 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 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 java.nio.ByteBuffer login; // required
    public java.lang.String user; // required
    public java.lang.String table; // required
    /**
     * 
     * @see TablePermission
     */
    public TablePermission perm; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      LOGIN((short)1, "login"),
      USER((short)2, "user"),
      TABLE((short)3, "table"),
      /**
       * 
       * @see TablePermission
       */
      PERM((short)4, "perm");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // LOGIN
            return LOGIN;
          case 2: // USER
            return USER;
          case 3: // TABLE
            return TABLE;
          case 4: // PERM
            return PERM;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.TABLE, new org.apache.thrift.meta_data.FieldMetaData("table", 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, TablePermission.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(grantTablePermission_args.class, metaDataMap);
    }

    public grantTablePermission_args() {
    }

    public grantTablePermission_args(
      java.nio.ByteBuffer login,
      java.lang.String user,
      java.lang.String table,
      TablePermission perm)
    {
      this();
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      this.user = user;
      this.table = table;
      this.perm = perm;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public grantTablePermission_args(grantTablePermission_args other) {
      if (other.isSetLogin()) {
        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
      }
      if (other.isSetUser()) {
        this.user = other.user;
      }
      if (other.isSetTable()) {
        this.table = other.table;
      }
      if (other.isSetPerm()) {
        this.perm = other.perm;
      }
    }

    public grantTablePermission_args deepCopy() {
      return new grantTablePermission_args(this);
    }

    @Override
    public void clear() {
      this.login = null;
      this.user = null;
      this.table = null;
      this.perm = null;
    }

    public byte[] getLogin() {
      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
      return login == null ? null : login.array();
    }

    public java.nio.ByteBuffer bufferForLogin() {
      return org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    public grantTablePermission_args setLogin(byte[] login) {
      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
      return this;
    }

    public grantTablePermission_args setLogin(java.nio.ByteBuffer login) {
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      return this;
    }

    public void unsetLogin() {
      this.login = null;
    }

    /** Returns true if field login is set (has been assigned a value) and false otherwise */
    public boolean isSetLogin() {
      return this.login != null;
    }

    public void setLoginIsSet(boolean value) {
      if (!value) {
        this.login = null;
      }
    }

    public java.lang.String getUser() {
      return this.user;
    }

    public grantTablePermission_args setUser(java.lang.String user) {
      this.user = user;
      return this;
    }

    public void unsetUser() {
      this.user = null;
    }

    /** Returns true if field user is set (has been assigned a value) and false otherwise */
    public boolean isSetUser() {
      return this.user != null;
    }

    public void setUserIsSet(boolean value) {
      if (!value) {
        this.user = null;
      }
    }

    public java.lang.String getTable() {
      return this.table;
    }

    public grantTablePermission_args setTable(java.lang.String table) {
      this.table = table;
      return this;
    }

    public void unsetTable() {
      this.table = null;
    }

    /** Returns true if field table is set (has been assigned a value) and false otherwise */
    public boolean isSetTable() {
      return this.table != null;
    }

    public void setTableIsSet(boolean value) {
      if (!value) {
        this.table = null;
      }
    }

    /**
     * 
     * @see TablePermission
     */
    public TablePermission getPerm() {
      return this.perm;
    }

    /**
     * 
     * @see TablePermission
     */
    public grantTablePermission_args setPerm(TablePermission perm) {
      this.perm = perm;
      return this;
    }

    public void unsetPerm() {
      this.perm = null;
    }

    /** Returns true if field perm is set (has been assigned a value) and false otherwise */
    public boolean isSetPerm() {
      return this.perm != null;
    }

    public void setPermIsSet(boolean value) {
      if (!value) {
        this.perm = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case LOGIN:
        if (value == null) {
          unsetLogin();
        } else {
          if (value instanceof byte[]) {
            setLogin((byte[])value);
          } else {
            setLogin((java.nio.ByteBuffer)value);
          }
        }
        break;

      case USER:
        if (value == null) {
          unsetUser();
        } else {
          setUser((java.lang.String)value);
        }
        break;

      case TABLE:
        if (value == null) {
          unsetTable();
        } else {
          setTable((java.lang.String)value);
        }
        break;

      case PERM:
        if (value == null) {
          unsetPerm();
        } else {
          setPerm((TablePermission)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case LOGIN:
        return getLogin();

      case USER:
        return getUser();

      case TABLE:
        return getTable();

      case PERM:
        return getPerm();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case LOGIN:
        return isSetLogin();
      case USER:
        return isSetUser();
      case TABLE:
        return isSetTable();
      case PERM:
        return isSetPerm();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof grantTablePermission_args)
        return this.equals((grantTablePermission_args)that);
      return false;
    }

    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();
      if (this_present_login || that_present_login) {
        if (!(this_present_login && that_present_login))
          return false;
        if (!this.login.equals(that.login))
          return false;
      }

      boolean this_present_user = true && this.isSetUser();
      boolean that_present_user = true && that.isSetUser();
      if (this_present_user || that_present_user) {
        if (!(this_present_user && that_present_user))
          return false;
        if (!this.user.equals(that.user))
          return false;
      }

      boolean this_present_table = true && this.isSetTable();
      boolean that_present_table = true && that.isSetTable();
      if (this_present_table || that_present_table) {
        if (!(this_present_table && that_present_table))
          return false;
        if (!this.table.equals(that.table))
          return false;
      }

      boolean this_present_perm = true && this.isSetPerm();
      boolean that_present_perm = true && that.isSetPerm();
      if (this_present_perm || that_present_perm) {
        if (!(this_present_perm && that_present_perm))
          return false;
        if (!this.perm.equals(that.perm))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
      if (isSetLogin())
        hashCode = hashCode * 8191 + login.hashCode();

      hashCode = hashCode * 8191 + ((isSetUser()) ? 131071 : 524287);
      if (isSetUser())
        hashCode = hashCode * 8191 + user.hashCode();

      hashCode = hashCode * 8191 + ((isSetTable()) ? 131071 : 524287);
      if (isSetTable())
        hashCode = hashCode * 8191 + table.hashCode();

      hashCode = hashCode * 8191 + ((isSetPerm()) ? 131071 : 524287);
      if (isSetPerm())
        hashCode = hashCode * 8191 + perm.getValue();

      return hashCode;
    }

    @Override
    public int compareTo(grantTablePermission_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLogin()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetUser()).compareTo(other.isSetUser());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetUser()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.user, other.user);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetTable()).compareTo(other.isSetTable());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetTable()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.table, other.table);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetPerm()).compareTo(other.isSetPerm());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetPerm()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.perm, other.perm);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("grantTablePermission_args(");
      boolean first = true;

      sb.append("login:");
      if (this.login == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.login, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("user:");
      if (this.user == null) {
        sb.append("null");
      } else {
        sb.append(this.user);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("table:");
      if (this.table == null) {
        sb.append("null");
      } else {
        sb.append(this.table);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("perm:");
      if (this.perm == null) {
        sb.append("null");
      } else {
        sb.append(this.perm);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class grantTablePermission_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public grantTablePermission_argsStandardScheme getScheme() {
        return new grantTablePermission_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // LOGIN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.login = iprot.readBinary();
                struct.setLoginIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // USER
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.user = iprot.readString();
                struct.setUserIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // TABLE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.table = iprot.readString();
                struct.setTableIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // PERM
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.perm = org.apache.accumulo.proxy.thrift.TablePermission.findByValue(iprot.readI32());
                struct.setPermIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, grantTablePermission_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.login != null) {
          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
          oprot.writeBinary(struct.login);
          oprot.writeFieldEnd();
        }
        if (struct.user != null) {
          oprot.writeFieldBegin(USER_FIELD_DESC);
          oprot.writeString(struct.user);
          oprot.writeFieldEnd();
        }
        if (struct.table != null) {
          oprot.writeFieldBegin(TABLE_FIELD_DESC);
          oprot.writeString(struct.table);
          oprot.writeFieldEnd();
        }
        if (struct.perm != null) {
          oprot.writeFieldBegin(PERM_FIELD_DESC);
          oprot.writeI32(struct.perm.getValue());
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class grantTablePermission_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public grantTablePermission_argsTupleScheme getScheme() {
        return new grantTablePermission_argsTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetUser()) {
          optionals.set(1);
        }
        if (struct.isSetTable()) {
          optionals.set(2);
        }
        if (struct.isSetPerm()) {
          optionals.set(3);
        }
        oprot.writeBitSet(optionals, 4);
        if (struct.isSetLogin()) {
          oprot.writeBinary(struct.login);
        }
        if (struct.isSetUser()) {
          oprot.writeString(struct.user);
        }
        if (struct.isSetTable()) {
          oprot.writeString(struct.table);
        }
        if (struct.isSetPerm()) {
          oprot.writeI32(struct.perm.getValue());
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, grantTablePermission_args struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.user = iprot.readString();
          struct.setUserIsSet(true);
        }
        if (incoming.get(2)) {
          struct.table = iprot.readString();
          struct.setTableIsSet(true);
        }
        if (incoming.get(3)) {
          struct.perm = org.apache.accumulo.proxy.thrift.TablePermission.findByValue(iprot.readI32());
          struct.setPermIsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("grantTablePermission_result");

    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField OUCH3_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch3", org.apache.thrift.protocol.TType.STRUCT, (short)3);

    private static final org.apache.thrift.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
    public TableNotFoundException ouch3; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      OUCH1((short)1, "ouch1"),
      OUCH2((short)2, "ouch2"),
      OUCH3((short)3, "ouch3");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // OUCH1
            return OUCH1;
          case 2: // OUCH2
            return OUCH2;
          case 3: // OUCH3
            return OUCH3;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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.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.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);
    }

    public grantTablePermission_result() {
    }

    public grantTablePermission_result(
      AccumuloException ouch1,
      AccumuloSecurityException ouch2,
      TableNotFoundException ouch3)
    {
      this();
      this.ouch1 = ouch1;
      this.ouch2 = ouch2;
      this.ouch3 = ouch3;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public grantTablePermission_result(grantTablePermission_result other) {
      if (other.isSetOuch1()) {
        this.ouch1 = new AccumuloException(other.ouch1);
      }
      if (other.isSetOuch2()) {
        this.ouch2 = new AccumuloSecurityException(other.ouch2);
      }
      if (other.isSetOuch3()) {
        this.ouch3 = new TableNotFoundException(other.ouch3);
      }
    }

    public grantTablePermission_result deepCopy() {
      return new grantTablePermission_result(this);
    }

    @Override
    public void clear() {
      this.ouch1 = null;
      this.ouch2 = null;
      this.ouch3 = null;
    }

    public AccumuloException getOuch1() {
      return this.ouch1;
    }

    public grantTablePermission_result setOuch1(AccumuloException ouch1) {
      this.ouch1 = ouch1;
      return this;
    }

    public void unsetOuch1() {
      this.ouch1 = null;
    }

    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch1() {
      return this.ouch1 != null;
    }

    public void setOuch1IsSet(boolean value) {
      if (!value) {
        this.ouch1 = null;
      }
    }

    public AccumuloSecurityException getOuch2() {
      return this.ouch2;
    }

    public grantTablePermission_result setOuch2(AccumuloSecurityException ouch2) {
      this.ouch2 = ouch2;
      return this;
    }

    public void unsetOuch2() {
      this.ouch2 = null;
    }

    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch2() {
      return this.ouch2 != null;
    }

    public void setOuch2IsSet(boolean value) {
      if (!value) {
        this.ouch2 = null;
      }
    }

    public TableNotFoundException getOuch3() {
      return this.ouch3;
    }

    public grantTablePermission_result setOuch3(TableNotFoundException ouch3) {
      this.ouch3 = ouch3;
      return this;
    }

    public void unsetOuch3() {
      this.ouch3 = null;
    }

    /** Returns true if field ouch3 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch3() {
      return this.ouch3 != null;
    }

    public void setOuch3IsSet(boolean value) {
      if (!value) {
        this.ouch3 = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case OUCH1:
        if (value == null) {
          unsetOuch1();
        } else {
          setOuch1((AccumuloException)value);
        }
        break;

      case OUCH2:
        if (value == null) {
          unsetOuch2();
        } else {
          setOuch2((AccumuloSecurityException)value);
        }
        break;

      case OUCH3:
        if (value == null) {
          unsetOuch3();
        } else {
          setOuch3((TableNotFoundException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case OUCH1:
        return getOuch1();

      case OUCH2:
        return getOuch2();

      case OUCH3:
        return getOuch3();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case OUCH1:
        return isSetOuch1();
      case OUCH2:
        return isSetOuch2();
      case OUCH3:
        return isSetOuch3();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof grantTablePermission_result)
        return this.equals((grantTablePermission_result)that);
      return false;
    }

    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();
      if (this_present_ouch1 || that_present_ouch1) {
        if (!(this_present_ouch1 && that_present_ouch1))
          return false;
        if (!this.ouch1.equals(that.ouch1))
          return false;
      }

      boolean this_present_ouch2 = true && this.isSetOuch2();
      boolean that_present_ouch2 = true && that.isSetOuch2();
      if (this_present_ouch2 || that_present_ouch2) {
        if (!(this_present_ouch2 && that_present_ouch2))
          return false;
        if (!this.ouch2.equals(that.ouch2))
          return false;
      }

      boolean this_present_ouch3 = true && this.isSetOuch3();
      boolean that_present_ouch3 = true && that.isSetOuch3();
      if (this_present_ouch3 || that_present_ouch3) {
        if (!(this_present_ouch3 && that_present_ouch3))
          return false;
        if (!this.ouch3.equals(that.ouch3))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
      if (isSetOuch1())
        hashCode = hashCode * 8191 + ouch1.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
      if (isSetOuch2())
        hashCode = hashCode * 8191 + ouch2.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
      if (isSetOuch3())
        hashCode = hashCode * 8191 + ouch3.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(grantTablePermission_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch1()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch2()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch3()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch3, other.ouch3);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("grantTablePermission_result(");
      boolean first = true;

      sb.append("ouch1:");
      if (this.ouch1 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch1);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch2:");
      if (this.ouch2 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch2);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch3:");
      if (this.ouch3 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch3);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class grantTablePermission_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public grantTablePermission_resultStandardScheme getScheme() {
        return new grantTablePermission_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // OUCH1
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch1 = new AccumuloException();
                struct.ouch1.read(iprot);
                struct.setOuch1IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OUCH2
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch2 = new AccumuloSecurityException();
                struct.ouch2.read(iprot);
                struct.setOuch2IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // OUCH3
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch3 = new TableNotFoundException();
                struct.ouch3.read(iprot);
                struct.setOuch3IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, grantTablePermission_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.ouch1 != null) {
          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
          struct.ouch1.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch2 != null) {
          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
          struct.ouch2.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch3 != null) {
          oprot.writeFieldBegin(OUCH3_FIELD_DESC);
          struct.ouch3.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class grantTablePermission_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public grantTablePermission_resultTupleScheme getScheme() {
        return new grantTablePermission_resultTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetOuch2()) {
          optionals.set(1);
        }
        if (struct.isSetOuch3()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetOuch1()) {
          struct.ouch1.write(oprot);
        }
        if (struct.isSetOuch2()) {
          struct.ouch2.write(oprot);
        }
        if (struct.isSetOuch3()) {
          struct.ouch3.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, grantTablePermission_result struct) throws org.apache.thrift.TException {
        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);
          struct.setOuch1IsSet(true);
        }
        if (incoming.get(1)) {
          struct.ouch2 = new AccumuloSecurityException();
          struct.ouch2.read(iprot);
          struct.setOuch2IsSet(true);
        }
        if (incoming.get(2)) {
          struct.ouch3 = new TableNotFoundException();
          struct.ouch3.read(iprot);
          struct.setOuch3IsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("hasSystemPermission_args");

    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField USER_FIELD_DESC = new org.apache.thrift.protocol.TField("user", org.apache.thrift.protocol.TType.STRING, (short)2);
    private static final org.apache.thrift.protocol.TField PERM_FIELD_DESC = new org.apache.thrift.protocol.TField("perm", org.apache.thrift.protocol.TType.I32, (short)3);

    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 java.nio.ByteBuffer login; // required
    public java.lang.String user; // required
    /**
     * 
     * @see SystemPermission
     */
    public SystemPermission perm; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      LOGIN((short)1, "login"),
      USER((short)2, "user"),
      /**
       * 
       * @see SystemPermission
       */
      PERM((short)3, "perm");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // LOGIN
            return LOGIN;
          case 2: // USER
            return USER;
          case 3: // PERM
            return PERM;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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 = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(hasSystemPermission_args.class, metaDataMap);
    }

    public hasSystemPermission_args() {
    }

    public hasSystemPermission_args(
      java.nio.ByteBuffer login,
      java.lang.String user,
      SystemPermission perm)
    {
      this();
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      this.user = user;
      this.perm = perm;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public hasSystemPermission_args(hasSystemPermission_args other) {
      if (other.isSetLogin()) {
        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
      }
      if (other.isSetUser()) {
        this.user = other.user;
      }
      if (other.isSetPerm()) {
        this.perm = other.perm;
      }
    }

    public hasSystemPermission_args deepCopy() {
      return new hasSystemPermission_args(this);
    }

    @Override
    public void clear() {
      this.login = null;
      this.user = null;
      this.perm = null;
    }

    public byte[] getLogin() {
      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
      return login == null ? null : login.array();
    }

    public java.nio.ByteBuffer bufferForLogin() {
      return org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    public hasSystemPermission_args setLogin(byte[] login) {
      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
      return this;
    }

    public hasSystemPermission_args setLogin(java.nio.ByteBuffer login) {
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      return this;
    }

    public void unsetLogin() {
      this.login = null;
    }

    /** Returns true if field login is set (has been assigned a value) and false otherwise */
    public boolean isSetLogin() {
      return this.login != null;
    }

    public void setLoginIsSet(boolean value) {
      if (!value) {
        this.login = null;
      }
    }

    public java.lang.String getUser() {
      return this.user;
    }

    public hasSystemPermission_args setUser(java.lang.String user) {
      this.user = user;
      return this;
    }

    public void unsetUser() {
      this.user = null;
    }

    /** Returns true if field user is set (has been assigned a value) and false otherwise */
    public boolean isSetUser() {
      return this.user != null;
    }

    public void setUserIsSet(boolean value) {
      if (!value) {
        this.user = null;
      }
    }

    /**
     * 
     * @see SystemPermission
     */
    public SystemPermission getPerm() {
      return this.perm;
    }

    /**
     * 
     * @see SystemPermission
     */
    public hasSystemPermission_args setPerm(SystemPermission perm) {
      this.perm = perm;
      return this;
    }

    public void unsetPerm() {
      this.perm = null;
    }

    /** Returns true if field perm is set (has been assigned a value) and false otherwise */
    public boolean isSetPerm() {
      return this.perm != null;
    }

    public void setPermIsSet(boolean value) {
      if (!value) {
        this.perm = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case LOGIN:
        if (value == null) {
          unsetLogin();
        } else {
          if (value instanceof byte[]) {
            setLogin((byte[])value);
          } else {
            setLogin((java.nio.ByteBuffer)value);
          }
        }
        break;

      case USER:
        if (value == null) {
          unsetUser();
        } else {
          setUser((java.lang.String)value);
        }
        break;

      case PERM:
        if (value == null) {
          unsetPerm();
        } else {
          setPerm((SystemPermission)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case LOGIN:
        return getLogin();

      case USER:
        return getUser();

      case PERM:
        return getPerm();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case LOGIN:
        return isSetLogin();
      case USER:
        return isSetUser();
      case PERM:
        return isSetPerm();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof hasSystemPermission_args)
        return this.equals((hasSystemPermission_args)that);
      return false;
    }

    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();
      if (this_present_login || that_present_login) {
        if (!(this_present_login && that_present_login))
          return false;
        if (!this.login.equals(that.login))
          return false;
      }

      boolean this_present_user = true && this.isSetUser();
      boolean that_present_user = true && that.isSetUser();
      if (this_present_user || that_present_user) {
        if (!(this_present_user && that_present_user))
          return false;
        if (!this.user.equals(that.user))
          return false;
      }

      boolean this_present_perm = true && this.isSetPerm();
      boolean that_present_perm = true && that.isSetPerm();
      if (this_present_perm || that_present_perm) {
        if (!(this_present_perm && that_present_perm))
          return false;
        if (!this.perm.equals(that.perm))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
      if (isSetLogin())
        hashCode = hashCode * 8191 + login.hashCode();

      hashCode = hashCode * 8191 + ((isSetUser()) ? 131071 : 524287);
      if (isSetUser())
        hashCode = hashCode * 8191 + user.hashCode();

      hashCode = hashCode * 8191 + ((isSetPerm()) ? 131071 : 524287);
      if (isSetPerm())
        hashCode = hashCode * 8191 + perm.getValue();

      return hashCode;
    }

    @Override
    public int compareTo(hasSystemPermission_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLogin()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetUser()).compareTo(other.isSetUser());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetUser()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.user, other.user);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetPerm()).compareTo(other.isSetPerm());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetPerm()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.perm, other.perm);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("hasSystemPermission_args(");
      boolean first = true;

      sb.append("login:");
      if (this.login == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.login, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("user:");
      if (this.user == null) {
        sb.append("null");
      } else {
        sb.append(this.user);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("perm:");
      if (this.perm == null) {
        sb.append("null");
      } else {
        sb.append(this.perm);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class hasSystemPermission_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public hasSystemPermission_argsStandardScheme getScheme() {
        return new hasSystemPermission_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // LOGIN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.login = iprot.readBinary();
                struct.setLoginIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // USER
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.user = iprot.readString();
                struct.setUserIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // PERM
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.perm = org.apache.accumulo.proxy.thrift.SystemPermission.findByValue(iprot.readI32());
                struct.setPermIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, hasSystemPermission_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.login != null) {
          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
          oprot.writeBinary(struct.login);
          oprot.writeFieldEnd();
        }
        if (struct.user != null) {
          oprot.writeFieldBegin(USER_FIELD_DESC);
          oprot.writeString(struct.user);
          oprot.writeFieldEnd();
        }
        if (struct.perm != null) {
          oprot.writeFieldBegin(PERM_FIELD_DESC);
          oprot.writeI32(struct.perm.getValue());
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    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 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 {
        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);
        }
        if (struct.isSetUser()) {
          optionals.set(1);
        }
        if (struct.isSetPerm()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetLogin()) {
          oprot.writeBinary(struct.login);
        }
        if (struct.isSetUser()) {
          oprot.writeString(struct.user);
        }
        if (struct.isSetPerm()) {
          oprot.writeI32(struct.perm.getValue());
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, hasSystemPermission_args struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.user = iprot.readString();
          struct.setUserIsSet(true);
        }
        if (incoming.get(2)) {
          struct.perm = org.apache.accumulo.proxy.thrift.SystemPermission.findByValue(iprot.readI32());
          struct.setPermIsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("hasSystemPermission_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.BOOL, (short)0);
    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);

    private static final org.apache.thrift.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
    public AccumuloSecurityException ouch2; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      OUCH1((short)1, "ouch1"),
      OUCH2((short)2, "ouch2");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // OUCH1
            return OUCH1;
          case 2: // OUCH2
            return OUCH2;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __SUCCESS_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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.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);
    }

    public hasSystemPermission_result() {
    }

    public hasSystemPermission_result(
      boolean success,
      AccumuloException ouch1,
      AccumuloSecurityException ouch2)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
      this.ouch1 = ouch1;
      this.ouch2 = ouch2;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public hasSystemPermission_result(hasSystemPermission_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
      if (other.isSetOuch1()) {
        this.ouch1 = new AccumuloException(other.ouch1);
      }
      if (other.isSetOuch2()) {
        this.ouch2 = new AccumuloSecurityException(other.ouch2);
      }
    }

    public hasSystemPermission_result deepCopy() {
      return new hasSystemPermission_result(this);
    }

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
      this.ouch1 = null;
      this.ouch2 = null;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public hasSystemPermission_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

    public void unsetSuccess() {
      __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 org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    public void setSuccessIsSet(boolean value) {
      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
    }

    public AccumuloException getOuch1() {
      return this.ouch1;
    }

    public hasSystemPermission_result setOuch1(AccumuloException ouch1) {
      this.ouch1 = ouch1;
      return this;
    }

    public void unsetOuch1() {
      this.ouch1 = null;
    }

    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch1() {
      return this.ouch1 != null;
    }

    public void setOuch1IsSet(boolean value) {
      if (!value) {
        this.ouch1 = null;
      }
    }

    public AccumuloSecurityException getOuch2() {
      return this.ouch2;
    }

    public hasSystemPermission_result setOuch2(AccumuloSecurityException ouch2) {
      this.ouch2 = ouch2;
      return this;
    }

    public void unsetOuch2() {
      this.ouch2 = null;
    }

    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch2() {
      return this.ouch2 != null;
    }

    public void setOuch2IsSet(boolean value) {
      if (!value) {
        this.ouch2 = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.lang.Boolean)value);
        }
        break;

      case OUCH1:
        if (value == null) {
          unsetOuch1();
        } else {
          setOuch1((AccumuloException)value);
        }
        break;

      case OUCH2:
        if (value == null) {
          unsetOuch2();
        } else {
          setOuch2((AccumuloSecurityException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return isSuccess();

      case OUCH1:
        return getOuch1();

      case OUCH2:
        return getOuch2();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case OUCH1:
        return isSetOuch1();
      case OUCH2:
        return isSetOuch2();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof hasSystemPermission_result)
        return this.equals((hasSystemPermission_result)that);
      return false;
    }

    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;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      boolean this_present_ouch1 = true && this.isSetOuch1();
      boolean that_present_ouch1 = true && that.isSetOuch1();
      if (this_present_ouch1 || that_present_ouch1) {
        if (!(this_present_ouch1 && that_present_ouch1))
          return false;
        if (!this.ouch1.equals(that.ouch1))
          return false;
      }

      boolean this_present_ouch2 = true && this.isSetOuch2();
      boolean that_present_ouch2 = true && that.isSetOuch2();
      if (this_present_ouch2 || that_present_ouch2) {
        if (!(this_present_ouch2 && that_present_ouch2))
          return false;
        if (!this.ouch2.equals(that.ouch2))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((success) ? 131071 : 524287);

      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
      if (isSetOuch1())
        hashCode = hashCode * 8191 + ouch1.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
      if (isSetOuch2())
        hashCode = hashCode * 8191 + ouch2.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(hasSystemPermission_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch1()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch2()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("hasSystemPermission_result(");
      boolean first = true;

      sb.append("success:");
      sb.append(this.success);
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch1:");
      if (this.ouch1 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch1);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch2:");
      if (this.ouch2 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch2);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, 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;
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class hasSystemPermission_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public hasSystemPermission_resultStandardScheme getScheme() {
        return new hasSystemPermission_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
                struct.success = iprot.readBool();
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // OUCH1
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch1 = new AccumuloException();
                struct.ouch1.read(iprot);
                struct.setOuch1IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OUCH2
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch2 = new AccumuloSecurityException();
                struct.ouch2.read(iprot);
                struct.setOuch2IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, hasSystemPermission_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.isSetSuccess()) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          oprot.writeBool(struct.success);
          oprot.writeFieldEnd();
        }
        if (struct.ouch1 != null) {
          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
          struct.ouch1.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch2 != null) {
          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
          struct.ouch2.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class hasSystemPermission_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public hasSystemPermission_resultTupleScheme getScheme() {
        return new hasSystemPermission_resultTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetOuch1()) {
          optionals.set(1);
        }
        if (struct.isSetOuch2()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
        if (struct.isSetOuch1()) {
          struct.ouch1.write(oprot);
        }
        if (struct.isSetOuch2()) {
          struct.ouch2.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, hasSystemPermission_result struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.ouch1 = new AccumuloException();
          struct.ouch1.read(iprot);
          struct.setOuch1IsSet(true);
        }
        if (incoming.get(2)) {
          struct.ouch2 = new AccumuloSecurityException();
          struct.ouch2.read(iprot);
          struct.setOuch2IsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("hasTablePermission_args");

    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField USER_FIELD_DESC = new org.apache.thrift.protocol.TField("user", org.apache.thrift.protocol.TType.STRING, (short)2);
    private static final org.apache.thrift.protocol.TField 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 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 java.nio.ByteBuffer login; // required
    public java.lang.String user; // required
    public java.lang.String table; // required
    /**
     * 
     * @see TablePermission
     */
    public TablePermission perm; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      LOGIN((short)1, "login"),
      USER((short)2, "user"),
      TABLE((short)3, "table"),
      /**
       * 
       * @see TablePermission
       */
      PERM((short)4, "perm");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // LOGIN
            return LOGIN;
          case 2: // USER
            return USER;
          case 3: // TABLE
            return TABLE;
          case 4: // PERM
            return PERM;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.TABLE, new org.apache.thrift.meta_data.FieldMetaData("table", 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, TablePermission.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(hasTablePermission_args.class, metaDataMap);
    }

    public hasTablePermission_args() {
    }

    public hasTablePermission_args(
      java.nio.ByteBuffer login,
      java.lang.String user,
      java.lang.String table,
      TablePermission perm)
    {
      this();
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      this.user = user;
      this.table = table;
      this.perm = perm;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public hasTablePermission_args(hasTablePermission_args other) {
      if (other.isSetLogin()) {
        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
      }
      if (other.isSetUser()) {
        this.user = other.user;
      }
      if (other.isSetTable()) {
        this.table = other.table;
      }
      if (other.isSetPerm()) {
        this.perm = other.perm;
      }
    }

    public hasTablePermission_args deepCopy() {
      return new hasTablePermission_args(this);
    }

    @Override
    public void clear() {
      this.login = null;
      this.user = null;
      this.table = null;
      this.perm = null;
    }

    public byte[] getLogin() {
      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
      return login == null ? null : login.array();
    }

    public java.nio.ByteBuffer bufferForLogin() {
      return org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    public hasTablePermission_args setLogin(byte[] login) {
      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
      return this;
    }

    public hasTablePermission_args setLogin(java.nio.ByteBuffer login) {
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      return this;
    }

    public void unsetLogin() {
      this.login = null;
    }

    /** Returns true if field login is set (has been assigned a value) and false otherwise */
    public boolean isSetLogin() {
      return this.login != null;
    }

    public void setLoginIsSet(boolean value) {
      if (!value) {
        this.login = null;
      }
    }

    public java.lang.String getUser() {
      return this.user;
    }

    public hasTablePermission_args setUser(java.lang.String user) {
      this.user = user;
      return this;
    }

    public void unsetUser() {
      this.user = null;
    }

    /** Returns true if field user is set (has been assigned a value) and false otherwise */
    public boolean isSetUser() {
      return this.user != null;
    }

    public void setUserIsSet(boolean value) {
      if (!value) {
        this.user = null;
      }
    }

    public java.lang.String getTable() {
      return this.table;
    }

    public hasTablePermission_args setTable(java.lang.String table) {
      this.table = table;
      return this;
    }

    public void unsetTable() {
      this.table = null;
    }

    /** Returns true if field table is set (has been assigned a value) and false otherwise */
    public boolean isSetTable() {
      return this.table != null;
    }

    public void setTableIsSet(boolean value) {
      if (!value) {
        this.table = null;
      }
    }

    /**
     * 
     * @see TablePermission
     */
    public TablePermission getPerm() {
      return this.perm;
    }

    /**
     * 
     * @see TablePermission
     */
    public hasTablePermission_args setPerm(TablePermission perm) {
      this.perm = perm;
      return this;
    }

    public void unsetPerm() {
      this.perm = null;
    }

    /** Returns true if field perm is set (has been assigned a value) and false otherwise */
    public boolean isSetPerm() {
      return this.perm != null;
    }

    public void setPermIsSet(boolean value) {
      if (!value) {
        this.perm = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case LOGIN:
        if (value == null) {
          unsetLogin();
        } else {
          if (value instanceof byte[]) {
            setLogin((byte[])value);
          } else {
            setLogin((java.nio.ByteBuffer)value);
          }
        }
        break;

      case USER:
        if (value == null) {
          unsetUser();
        } else {
          setUser((java.lang.String)value);
        }
        break;

      case TABLE:
        if (value == null) {
          unsetTable();
        } else {
          setTable((java.lang.String)value);
        }
        break;

      case PERM:
        if (value == null) {
          unsetPerm();
        } else {
          setPerm((TablePermission)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case LOGIN:
        return getLogin();

      case USER:
        return getUser();

      case TABLE:
        return getTable();

      case PERM:
        return getPerm();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case LOGIN:
        return isSetLogin();
      case USER:
        return isSetUser();
      case TABLE:
        return isSetTable();
      case PERM:
        return isSetPerm();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof hasTablePermission_args)
        return this.equals((hasTablePermission_args)that);
      return false;
    }

    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();
      if (this_present_login || that_present_login) {
        if (!(this_present_login && that_present_login))
          return false;
        if (!this.login.equals(that.login))
          return false;
      }

      boolean this_present_user = true && this.isSetUser();
      boolean that_present_user = true && that.isSetUser();
      if (this_present_user || that_present_user) {
        if (!(this_present_user && that_present_user))
          return false;
        if (!this.user.equals(that.user))
          return false;
      }

      boolean this_present_table = true && this.isSetTable();
      boolean that_present_table = true && that.isSetTable();
      if (this_present_table || that_present_table) {
        if (!(this_present_table && that_present_table))
          return false;
        if (!this.table.equals(that.table))
          return false;
      }

      boolean this_present_perm = true && this.isSetPerm();
      boolean that_present_perm = true && that.isSetPerm();
      if (this_present_perm || that_present_perm) {
        if (!(this_present_perm && that_present_perm))
          return false;
        if (!this.perm.equals(that.perm))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
      if (isSetLogin())
        hashCode = hashCode * 8191 + login.hashCode();

      hashCode = hashCode * 8191 + ((isSetUser()) ? 131071 : 524287);
      if (isSetUser())
        hashCode = hashCode * 8191 + user.hashCode();

      hashCode = hashCode * 8191 + ((isSetTable()) ? 131071 : 524287);
      if (isSetTable())
        hashCode = hashCode * 8191 + table.hashCode();

      hashCode = hashCode * 8191 + ((isSetPerm()) ? 131071 : 524287);
      if (isSetPerm())
        hashCode = hashCode * 8191 + perm.getValue();

      return hashCode;
    }

    @Override
    public int compareTo(hasTablePermission_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLogin()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetUser()).compareTo(other.isSetUser());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetUser()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.user, other.user);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetTable()).compareTo(other.isSetTable());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetTable()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.table, other.table);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetPerm()).compareTo(other.isSetPerm());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetPerm()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.perm, other.perm);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("hasTablePermission_args(");
      boolean first = true;

      sb.append("login:");
      if (this.login == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.login, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("user:");
      if (this.user == null) {
        sb.append("null");
      } else {
        sb.append(this.user);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("table:");
      if (this.table == null) {
        sb.append("null");
      } else {
        sb.append(this.table);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("perm:");
      if (this.perm == null) {
        sb.append("null");
      } else {
        sb.append(this.perm);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class hasTablePermission_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public hasTablePermission_argsStandardScheme getScheme() {
        return new hasTablePermission_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // LOGIN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.login = iprot.readBinary();
                struct.setLoginIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // USER
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.user = iprot.readString();
                struct.setUserIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // TABLE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.table = iprot.readString();
                struct.setTableIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // PERM
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.perm = org.apache.accumulo.proxy.thrift.TablePermission.findByValue(iprot.readI32());
                struct.setPermIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, hasTablePermission_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.login != null) {
          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
          oprot.writeBinary(struct.login);
          oprot.writeFieldEnd();
        }
        if (struct.user != null) {
          oprot.writeFieldBegin(USER_FIELD_DESC);
          oprot.writeString(struct.user);
          oprot.writeFieldEnd();
        }
        if (struct.table != null) {
          oprot.writeFieldBegin(TABLE_FIELD_DESC);
          oprot.writeString(struct.table);
          oprot.writeFieldEnd();
        }
        if (struct.perm != null) {
          oprot.writeFieldBegin(PERM_FIELD_DESC);
          oprot.writeI32(struct.perm.getValue());
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class hasTablePermission_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public hasTablePermission_argsTupleScheme getScheme() {
        return new hasTablePermission_argsTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetUser()) {
          optionals.set(1);
        }
        if (struct.isSetTable()) {
          optionals.set(2);
        }
        if (struct.isSetPerm()) {
          optionals.set(3);
        }
        oprot.writeBitSet(optionals, 4);
        if (struct.isSetLogin()) {
          oprot.writeBinary(struct.login);
        }
        if (struct.isSetUser()) {
          oprot.writeString(struct.user);
        }
        if (struct.isSetTable()) {
          oprot.writeString(struct.table);
        }
        if (struct.isSetPerm()) {
          oprot.writeI32(struct.perm.getValue());
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, hasTablePermission_args struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.user = iprot.readString();
          struct.setUserIsSet(true);
        }
        if (incoming.get(2)) {
          struct.table = iprot.readString();
          struct.setTableIsSet(true);
        }
        if (incoming.get(3)) {
          struct.perm = org.apache.accumulo.proxy.thrift.TablePermission.findByValue(iprot.readI32());
          struct.setPermIsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("hasTablePermission_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.BOOL, (short)0);
    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField OUCH3_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch3", org.apache.thrift.protocol.TType.STRUCT, (short)3);

    private static final 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
    public AccumuloSecurityException ouch2; // required
    public TableNotFoundException ouch3; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      OUCH1((short)1, "ouch1"),
      OUCH2((short)2, "ouch2"),
      OUCH3((short)3, "ouch3");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // OUCH1
            return OUCH1;
          case 2: // OUCH2
            return OUCH2;
          case 3: // OUCH3
            return OUCH3;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __SUCCESS_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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.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.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);
    }

    public hasTablePermission_result() {
    }

    public hasTablePermission_result(
      boolean success,
      AccumuloException ouch1,
      AccumuloSecurityException ouch2,
      TableNotFoundException ouch3)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
      this.ouch1 = ouch1;
      this.ouch2 = ouch2;
      this.ouch3 = ouch3;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public hasTablePermission_result(hasTablePermission_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
      if (other.isSetOuch1()) {
        this.ouch1 = new AccumuloException(other.ouch1);
      }
      if (other.isSetOuch2()) {
        this.ouch2 = new AccumuloSecurityException(other.ouch2);
      }
      if (other.isSetOuch3()) {
        this.ouch3 = new TableNotFoundException(other.ouch3);
      }
    }

    public hasTablePermission_result deepCopy() {
      return new hasTablePermission_result(this);
    }

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
      this.ouch1 = null;
      this.ouch2 = null;
      this.ouch3 = null;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public hasTablePermission_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

    public void unsetSuccess() {
      __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 org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    public void setSuccessIsSet(boolean value) {
      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
    }

    public AccumuloException getOuch1() {
      return this.ouch1;
    }

    public hasTablePermission_result setOuch1(AccumuloException ouch1) {
      this.ouch1 = ouch1;
      return this;
    }

    public void unsetOuch1() {
      this.ouch1 = null;
    }

    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch1() {
      return this.ouch1 != null;
    }

    public void setOuch1IsSet(boolean value) {
      if (!value) {
        this.ouch1 = null;
      }
    }

    public AccumuloSecurityException getOuch2() {
      return this.ouch2;
    }

    public hasTablePermission_result setOuch2(AccumuloSecurityException ouch2) {
      this.ouch2 = ouch2;
      return this;
    }

    public void unsetOuch2() {
      this.ouch2 = null;
    }

    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch2() {
      return this.ouch2 != null;
    }

    public void setOuch2IsSet(boolean value) {
      if (!value) {
        this.ouch2 = null;
      }
    }

    public TableNotFoundException getOuch3() {
      return this.ouch3;
    }

    public hasTablePermission_result setOuch3(TableNotFoundException ouch3) {
      this.ouch3 = ouch3;
      return this;
    }

    public void unsetOuch3() {
      this.ouch3 = null;
    }

    /** Returns true if field ouch3 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch3() {
      return this.ouch3 != null;
    }

    public void setOuch3IsSet(boolean value) {
      if (!value) {
        this.ouch3 = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.lang.Boolean)value);
        }
        break;

      case OUCH1:
        if (value == null) {
          unsetOuch1();
        } else {
          setOuch1((AccumuloException)value);
        }
        break;

      case OUCH2:
        if (value == null) {
          unsetOuch2();
        } else {
          setOuch2((AccumuloSecurityException)value);
        }
        break;

      case OUCH3:
        if (value == null) {
          unsetOuch3();
        } else {
          setOuch3((TableNotFoundException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return isSuccess();

      case OUCH1:
        return getOuch1();

      case OUCH2:
        return getOuch2();

      case OUCH3:
        return getOuch3();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case OUCH1:
        return isSetOuch1();
      case OUCH2:
        return isSetOuch2();
      case OUCH3:
        return isSetOuch3();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof hasTablePermission_result)
        return this.equals((hasTablePermission_result)that);
      return false;
    }

    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;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      boolean this_present_ouch1 = true && this.isSetOuch1();
      boolean that_present_ouch1 = true && that.isSetOuch1();
      if (this_present_ouch1 || that_present_ouch1) {
        if (!(this_present_ouch1 && that_present_ouch1))
          return false;
        if (!this.ouch1.equals(that.ouch1))
          return false;
      }

      boolean this_present_ouch2 = true && this.isSetOuch2();
      boolean that_present_ouch2 = true && that.isSetOuch2();
      if (this_present_ouch2 || that_present_ouch2) {
        if (!(this_present_ouch2 && that_present_ouch2))
          return false;
        if (!this.ouch2.equals(that.ouch2))
          return false;
      }

      boolean this_present_ouch3 = true && this.isSetOuch3();
      boolean that_present_ouch3 = true && that.isSetOuch3();
      if (this_present_ouch3 || that_present_ouch3) {
        if (!(this_present_ouch3 && that_present_ouch3))
          return false;
        if (!this.ouch3.equals(that.ouch3))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((success) ? 131071 : 524287);

      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
      if (isSetOuch1())
        hashCode = hashCode * 8191 + ouch1.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
      if (isSetOuch2())
        hashCode = hashCode * 8191 + ouch2.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
      if (isSetOuch3())
        hashCode = hashCode * 8191 + ouch3.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(hasTablePermission_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch1()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch2()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch3()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch3, other.ouch3);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("hasTablePermission_result(");
      boolean first = true;

      sb.append("success:");
      sb.append(this.success);
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch1:");
      if (this.ouch1 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch1);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch2:");
      if (this.ouch2 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch2);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch3:");
      if (this.ouch3 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch3);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, 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;
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class hasTablePermission_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public hasTablePermission_resultStandardScheme getScheme() {
        return new hasTablePermission_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
                struct.success = iprot.readBool();
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // OUCH1
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch1 = new AccumuloException();
                struct.ouch1.read(iprot);
                struct.setOuch1IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OUCH2
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch2 = new AccumuloSecurityException();
                struct.ouch2.read(iprot);
                struct.setOuch2IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // OUCH3
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch3 = new TableNotFoundException();
                struct.ouch3.read(iprot);
                struct.setOuch3IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, hasTablePermission_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.isSetSuccess()) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          oprot.writeBool(struct.success);
          oprot.writeFieldEnd();
        }
        if (struct.ouch1 != null) {
          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
          struct.ouch1.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch2 != null) {
          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
          struct.ouch2.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch3 != null) {
          oprot.writeFieldBegin(OUCH3_FIELD_DESC);
          struct.ouch3.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class hasTablePermission_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public hasTablePermission_resultTupleScheme getScheme() {
        return new hasTablePermission_resultTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetOuch1()) {
          optionals.set(1);
        }
        if (struct.isSetOuch2()) {
          optionals.set(2);
        }
        if (struct.isSetOuch3()) {
          optionals.set(3);
        }
        oprot.writeBitSet(optionals, 4);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
        if (struct.isSetOuch1()) {
          struct.ouch1.write(oprot);
        }
        if (struct.isSetOuch2()) {
          struct.ouch2.write(oprot);
        }
        if (struct.isSetOuch3()) {
          struct.ouch3.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, hasTablePermission_result struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.ouch1 = new AccumuloException();
          struct.ouch1.read(iprot);
          struct.setOuch1IsSet(true);
        }
        if (incoming.get(2)) {
          struct.ouch2 = new AccumuloSecurityException();
          struct.ouch2.read(iprot);
          struct.setOuch2IsSet(true);
        }
        if (incoming.get(3)) {
          struct.ouch3 = new TableNotFoundException();
          struct.ouch3.read(iprot);
          struct.setOuch3IsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("listLocalUsers_args");

    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new listLocalUsers_argsStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new listLocalUsers_argsTupleSchemeFactory();

    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 java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // LOGIN
            return LOGIN;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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 = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(listLocalUsers_args.class, metaDataMap);
    }

    public listLocalUsers_args() {
    }

    public listLocalUsers_args(
      java.nio.ByteBuffer login)
    {
      this();
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public listLocalUsers_args(listLocalUsers_args other) {
      if (other.isSetLogin()) {
        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
      }
    }

    public listLocalUsers_args deepCopy() {
      return new listLocalUsers_args(this);
    }

    @Override
    public void clear() {
      this.login = null;
    }

    public byte[] getLogin() {
      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
      return login == null ? null : login.array();
    }

    public java.nio.ByteBuffer bufferForLogin() {
      return org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    public listLocalUsers_args setLogin(byte[] login) {
      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
      return this;
    }

    public listLocalUsers_args setLogin(java.nio.ByteBuffer login) {
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      return this;
    }

    public void unsetLogin() {
      this.login = null;
    }

    /** Returns true if field login is set (has been assigned a value) and false otherwise */
    public boolean isSetLogin() {
      return this.login != null;
    }

    public void setLoginIsSet(boolean value) {
      if (!value) {
        this.login = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case LOGIN:
        if (value == null) {
          unsetLogin();
        } else {
          if (value instanceof byte[]) {
            setLogin((byte[])value);
          } else {
            setLogin((java.nio.ByteBuffer)value);
          }
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case LOGIN:
        return getLogin();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case LOGIN:
        return isSetLogin();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof listLocalUsers_args)
        return this.equals((listLocalUsers_args)that);
      return false;
    }

    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();
      if (this_present_login || that_present_login) {
        if (!(this_present_login && that_present_login))
          return false;
        if (!this.login.equals(that.login))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
      if (isSetLogin())
        hashCode = hashCode * 8191 + login.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(listLocalUsers_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLogin()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("listLocalUsers_args(");
      boolean first = true;

      sb.append("login:");
      if (this.login == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.login, sb);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class listLocalUsers_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public listLocalUsers_argsStandardScheme getScheme() {
        return new listLocalUsers_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // LOGIN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.login = iprot.readBinary();
                struct.setLoginIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, listLocalUsers_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.login != null) {
          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
          oprot.writeBinary(struct.login);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class listLocalUsers_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public listLocalUsers_argsTupleScheme getScheme() {
        return new listLocalUsers_argsTupleScheme();
      }
    }

    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 {
        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);
        }
        oprot.writeBitSet(optionals, 1);
        if (struct.isSetLogin()) {
          oprot.writeBinary(struct.login);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, listLocalUsers_args struct) throws org.apache.thrift.TException {
        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);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("listLocalUsers_result");

    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 org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField OUCH3_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch3", org.apache.thrift.protocol.TType.STRUCT, (short)3);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new listLocalUsers_resultStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new listLocalUsers_resultTupleSchemeFactory();

    public java.util.Set<java.lang.String> success; // required
    public AccumuloException ouch1; // required
    public AccumuloSecurityException ouch2; // required
    public TableNotFoundException ouch3; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      OUCH1((short)1, "ouch1"),
      OUCH2((short)2, "ouch2"),
      OUCH3((short)3, "ouch3");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // OUCH1
            return OUCH1;
          case 2: // OUCH2
            return OUCH2;
          case 3: // OUCH3
            return OUCH3;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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.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.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);
    }

    public listLocalUsers_result() {
    }

    public listLocalUsers_result(
      java.util.Set<java.lang.String> success,
      AccumuloException ouch1,
      AccumuloSecurityException ouch2,
      TableNotFoundException ouch3)
    {
      this();
      this.success = success;
      this.ouch1 = ouch1;
      this.ouch2 = ouch2;
      this.ouch3 = ouch3;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public listLocalUsers_result(listLocalUsers_result other) {
      if (other.isSetSuccess()) {
        java.util.Set<java.lang.String> __this__success = new java.util.HashSet<java.lang.String>(other.success);
        this.success = __this__success;
      }
      if (other.isSetOuch1()) {
        this.ouch1 = new AccumuloException(other.ouch1);
      }
      if (other.isSetOuch2()) {
        this.ouch2 = new AccumuloSecurityException(other.ouch2);
      }
      if (other.isSetOuch3()) {
        this.ouch3 = new TableNotFoundException(other.ouch3);
      }
    }

    public listLocalUsers_result deepCopy() {
      return new listLocalUsers_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ouch1 = null;
      this.ouch2 = null;
      this.ouch3 = null;
    }

    public int getSuccessSize() {
      return (this.success == null) ? 0 : this.success.size();
    }

    public java.util.Iterator<java.lang.String> getSuccessIterator() {
      return (this.success == null) ? null : this.success.iterator();
    }

    public void addToSuccess(java.lang.String elem) {
      if (this.success == null) {
        this.success = new java.util.HashSet<java.lang.String>();
      }
      this.success.add(elem);
    }

    public java.util.Set<java.lang.String> getSuccess() {
      return this.success;
    }

    public listLocalUsers_result setSuccess(java.util.Set<java.lang.String> success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return this.success != null;
    }

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public AccumuloException getOuch1() {
      return this.ouch1;
    }

    public listLocalUsers_result setOuch1(AccumuloException ouch1) {
      this.ouch1 = ouch1;
      return this;
    }

    public void unsetOuch1() {
      this.ouch1 = null;
    }

    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch1() {
      return this.ouch1 != null;
    }

    public void setOuch1IsSet(boolean value) {
      if (!value) {
        this.ouch1 = null;
      }
    }

    public AccumuloSecurityException getOuch2() {
      return this.ouch2;
    }

    public listLocalUsers_result setOuch2(AccumuloSecurityException ouch2) {
      this.ouch2 = ouch2;
      return this;
    }

    public void unsetOuch2() {
      this.ouch2 = null;
    }

    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch2() {
      return this.ouch2 != null;
    }

    public void setOuch2IsSet(boolean value) {
      if (!value) {
        this.ouch2 = null;
      }
    }

    public TableNotFoundException getOuch3() {
      return this.ouch3;
    }

    public listLocalUsers_result setOuch3(TableNotFoundException ouch3) {
      this.ouch3 = ouch3;
      return this;
    }

    public void unsetOuch3() {
      this.ouch3 = null;
    }

    /** Returns true if field ouch3 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch3() {
      return this.ouch3 != null;
    }

    public void setOuch3IsSet(boolean value) {
      if (!value) {
        this.ouch3 = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.util.Set<java.lang.String>)value);
        }
        break;

      case OUCH1:
        if (value == null) {
          unsetOuch1();
        } else {
          setOuch1((AccumuloException)value);
        }
        break;

      case OUCH2:
        if (value == null) {
          unsetOuch2();
        } else {
          setOuch2((AccumuloSecurityException)value);
        }
        break;

      case OUCH3:
        if (value == null) {
          unsetOuch3();
        } else {
          setOuch3((TableNotFoundException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case OUCH1:
        return getOuch1();

      case OUCH2:
        return getOuch2();

      case OUCH3:
        return getOuch3();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case OUCH1:
        return isSetOuch1();
      case OUCH2:
        return isSetOuch2();
      case OUCH3:
        return isSetOuch3();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof listLocalUsers_result)
        return this.equals((listLocalUsers_result)that);
      return false;
    }

    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();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ouch1 = true && this.isSetOuch1();
      boolean that_present_ouch1 = true && that.isSetOuch1();
      if (this_present_ouch1 || that_present_ouch1) {
        if (!(this_present_ouch1 && that_present_ouch1))
          return false;
        if (!this.ouch1.equals(that.ouch1))
          return false;
      }

      boolean this_present_ouch2 = true && this.isSetOuch2();
      boolean that_present_ouch2 = true && that.isSetOuch2();
      if (this_present_ouch2 || that_present_ouch2) {
        if (!(this_present_ouch2 && that_present_ouch2))
          return false;
        if (!this.ouch2.equals(that.ouch2))
          return false;
      }

      boolean this_present_ouch3 = true && this.isSetOuch3();
      boolean that_present_ouch3 = true && that.isSetOuch3();
      if (this_present_ouch3 || that_present_ouch3) {
        if (!(this_present_ouch3 && that_present_ouch3))
          return false;
        if (!this.ouch3.equals(that.ouch3))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
      if (isSetSuccess())
        hashCode = hashCode * 8191 + success.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
      if (isSetOuch1())
        hashCode = hashCode * 8191 + ouch1.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
      if (isSetOuch2())
        hashCode = hashCode * 8191 + ouch2.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
      if (isSetOuch3())
        hashCode = hashCode * 8191 + ouch3.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(listLocalUsers_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch1()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch2()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch3()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch3, other.ouch3);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("listLocalUsers_result(");
      boolean first = true;

      sb.append("success:");
      if (this.success == null) {
        sb.append("null");
      } else {
        sb.append(this.success);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch1:");
      if (this.ouch1 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch1);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch2:");
      if (this.ouch2 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch2);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch3:");
      if (this.ouch3 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch3);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class listLocalUsers_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public listLocalUsers_resultStandardScheme getScheme() {
        return new listLocalUsers_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.SET) {
                {
                  org.apache.thrift.protocol.TSet _set434 = iprot.readSetBegin();
                  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();
                    struct.success.add(_elem435);
                  }
                  iprot.readSetEnd();
                }
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // OUCH1
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch1 = new AccumuloException();
                struct.ouch1.read(iprot);
                struct.setOuch1IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OUCH2
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch2 = new AccumuloSecurityException();
                struct.ouch2.read(iprot);
                struct.setOuch2IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // OUCH3
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch3 = new TableNotFoundException();
                struct.ouch3.read(iprot);
                struct.setOuch3IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, listLocalUsers_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          {
            oprot.writeSetBegin(new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRING, struct.success.size()));
            for (java.lang.String _iter437 : struct.success)
            {
              oprot.writeString(_iter437);
            }
            oprot.writeSetEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.ouch1 != null) {
          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
          struct.ouch1.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch2 != null) {
          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
          struct.ouch2.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch3 != null) {
          oprot.writeFieldBegin(OUCH3_FIELD_DESC);
          struct.ouch3.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class listLocalUsers_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public listLocalUsers_resultTupleScheme getScheme() {
        return new listLocalUsers_resultTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetOuch1()) {
          optionals.set(1);
        }
        if (struct.isSetOuch2()) {
          optionals.set(2);
        }
        if (struct.isSetOuch3()) {
          optionals.set(3);
        }
        oprot.writeBitSet(optionals, 4);
        if (struct.isSetSuccess()) {
          {
            oprot.writeI32(struct.success.size());
            for (java.lang.String _iter438 : struct.success)
            {
              oprot.writeString(_iter438);
            }
          }
        }
        if (struct.isSetOuch1()) {
          struct.ouch1.write(oprot);
        }
        if (struct.isSetOuch2()) {
          struct.ouch2.write(oprot);
        }
        if (struct.isSetOuch3()) {
          struct.ouch3.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, listLocalUsers_result struct) throws org.apache.thrift.TException {
        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 java.util.HashSet<java.lang.String>(2*_set439.size);
            java.lang.String _elem440;
            for (int _i441 = 0; _i441 < _set439.size; ++_i441)
            {
              _elem440 = iprot.readString();
              struct.success.add(_elem440);
            }
          }
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ouch1 = new AccumuloException();
          struct.ouch1.read(iprot);
          struct.setOuch1IsSet(true);
        }
        if (incoming.get(2)) {
          struct.ouch2 = new AccumuloSecurityException();
          struct.ouch2.read(iprot);
          struct.setOuch2IsSet(true);
        }
        if (incoming.get(3)) {
          struct.ouch3 = new TableNotFoundException();
          struct.ouch3.read(iprot);
          struct.setOuch3IsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("revokeSystemPermission_args");

    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField USER_FIELD_DESC = new org.apache.thrift.protocol.TField("user", org.apache.thrift.protocol.TType.STRING, (short)2);
    private static final org.apache.thrift.protocol.TField PERM_FIELD_DESC = new org.apache.thrift.protocol.TField("perm", org.apache.thrift.protocol.TType.I32, (short)3);

    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 java.nio.ByteBuffer login; // required
    public java.lang.String user; // required
    /**
     * 
     * @see SystemPermission
     */
    public SystemPermission perm; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      LOGIN((short)1, "login"),
      USER((short)2, "user"),
      /**
       * 
       * @see SystemPermission
       */
      PERM((short)3, "perm");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // LOGIN
            return LOGIN;
          case 2: // USER
            return USER;
          case 3: // PERM
            return PERM;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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 = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(revokeSystemPermission_args.class, metaDataMap);
    }

    public revokeSystemPermission_args() {
    }

    public revokeSystemPermission_args(
      java.nio.ByteBuffer login,
      java.lang.String user,
      SystemPermission perm)
    {
      this();
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      this.user = user;
      this.perm = perm;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public revokeSystemPermission_args(revokeSystemPermission_args other) {
      if (other.isSetLogin()) {
        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
      }
      if (other.isSetUser()) {
        this.user = other.user;
      }
      if (other.isSetPerm()) {
        this.perm = other.perm;
      }
    }

    public revokeSystemPermission_args deepCopy() {
      return new revokeSystemPermission_args(this);
    }

    @Override
    public void clear() {
      this.login = null;
      this.user = null;
      this.perm = null;
    }

    public byte[] getLogin() {
      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
      return login == null ? null : login.array();
    }

    public java.nio.ByteBuffer bufferForLogin() {
      return org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    public revokeSystemPermission_args setLogin(byte[] login) {
      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
      return this;
    }

    public revokeSystemPermission_args setLogin(java.nio.ByteBuffer login) {
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      return this;
    }

    public void unsetLogin() {
      this.login = null;
    }

    /** Returns true if field login is set (has been assigned a value) and false otherwise */
    public boolean isSetLogin() {
      return this.login != null;
    }

    public void setLoginIsSet(boolean value) {
      if (!value) {
        this.login = null;
      }
    }

    public java.lang.String getUser() {
      return this.user;
    }

    public revokeSystemPermission_args setUser(java.lang.String user) {
      this.user = user;
      return this;
    }

    public void unsetUser() {
      this.user = null;
    }

    /** Returns true if field user is set (has been assigned a value) and false otherwise */
    public boolean isSetUser() {
      return this.user != null;
    }

    public void setUserIsSet(boolean value) {
      if (!value) {
        this.user = null;
      }
    }

    /**
     * 
     * @see SystemPermission
     */
    public SystemPermission getPerm() {
      return this.perm;
    }

    /**
     * 
     * @see SystemPermission
     */
    public revokeSystemPermission_args setPerm(SystemPermission perm) {
      this.perm = perm;
      return this;
    }

    public void unsetPerm() {
      this.perm = null;
    }

    /** Returns true if field perm is set (has been assigned a value) and false otherwise */
    public boolean isSetPerm() {
      return this.perm != null;
    }

    public void setPermIsSet(boolean value) {
      if (!value) {
        this.perm = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case LOGIN:
        if (value == null) {
          unsetLogin();
        } else {
          if (value instanceof byte[]) {
            setLogin((byte[])value);
          } else {
            setLogin((java.nio.ByteBuffer)value);
          }
        }
        break;

      case USER:
        if (value == null) {
          unsetUser();
        } else {
          setUser((java.lang.String)value);
        }
        break;

      case PERM:
        if (value == null) {
          unsetPerm();
        } else {
          setPerm((SystemPermission)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case LOGIN:
        return getLogin();

      case USER:
        return getUser();

      case PERM:
        return getPerm();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case LOGIN:
        return isSetLogin();
      case USER:
        return isSetUser();
      case PERM:
        return isSetPerm();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof revokeSystemPermission_args)
        return this.equals((revokeSystemPermission_args)that);
      return false;
    }

    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();
      if (this_present_login || that_present_login) {
        if (!(this_present_login && that_present_login))
          return false;
        if (!this.login.equals(that.login))
          return false;
      }

      boolean this_present_user = true && this.isSetUser();
      boolean that_present_user = true && that.isSetUser();
      if (this_present_user || that_present_user) {
        if (!(this_present_user && that_present_user))
          return false;
        if (!this.user.equals(that.user))
          return false;
      }

      boolean this_present_perm = true && this.isSetPerm();
      boolean that_present_perm = true && that.isSetPerm();
      if (this_present_perm || that_present_perm) {
        if (!(this_present_perm && that_present_perm))
          return false;
        if (!this.perm.equals(that.perm))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
      if (isSetLogin())
        hashCode = hashCode * 8191 + login.hashCode();

      hashCode = hashCode * 8191 + ((isSetUser()) ? 131071 : 524287);
      if (isSetUser())
        hashCode = hashCode * 8191 + user.hashCode();

      hashCode = hashCode * 8191 + ((isSetPerm()) ? 131071 : 524287);
      if (isSetPerm())
        hashCode = hashCode * 8191 + perm.getValue();

      return hashCode;
    }

    @Override
    public int compareTo(revokeSystemPermission_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLogin()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetUser()).compareTo(other.isSetUser());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetUser()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.user, other.user);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetPerm()).compareTo(other.isSetPerm());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetPerm()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.perm, other.perm);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("revokeSystemPermission_args(");
      boolean first = true;

      sb.append("login:");
      if (this.login == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.login, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("user:");
      if (this.user == null) {
        sb.append("null");
      } else {
        sb.append(this.user);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("perm:");
      if (this.perm == null) {
        sb.append("null");
      } else {
        sb.append(this.perm);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class revokeSystemPermission_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public revokeSystemPermission_argsStandardScheme getScheme() {
        return new revokeSystemPermission_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // LOGIN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.login = iprot.readBinary();
                struct.setLoginIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // USER
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.user = iprot.readString();
                struct.setUserIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // PERM
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.perm = org.apache.accumulo.proxy.thrift.SystemPermission.findByValue(iprot.readI32());
                struct.setPermIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, revokeSystemPermission_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.login != null) {
          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
          oprot.writeBinary(struct.login);
          oprot.writeFieldEnd();
        }
        if (struct.user != null) {
          oprot.writeFieldBegin(USER_FIELD_DESC);
          oprot.writeString(struct.user);
          oprot.writeFieldEnd();
        }
        if (struct.perm != null) {
          oprot.writeFieldBegin(PERM_FIELD_DESC);
          oprot.writeI32(struct.perm.getValue());
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    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 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 {
        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);
        }
        if (struct.isSetUser()) {
          optionals.set(1);
        }
        if (struct.isSetPerm()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetLogin()) {
          oprot.writeBinary(struct.login);
        }
        if (struct.isSetUser()) {
          oprot.writeString(struct.user);
        }
        if (struct.isSetPerm()) {
          oprot.writeI32(struct.perm.getValue());
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, revokeSystemPermission_args struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.user = iprot.readString();
          struct.setUserIsSet(true);
        }
        if (incoming.get(2)) {
          struct.perm = org.apache.accumulo.proxy.thrift.SystemPermission.findByValue(iprot.readI32());
          struct.setPermIsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("revokeSystemPermission_result");

    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);

    private static final org.apache.thrift.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

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      OUCH1((short)1, "ouch1"),
      OUCH2((short)2, "ouch2");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // OUCH1
            return OUCH1;
          case 2: // OUCH2
            return OUCH2;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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.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);
    }

    public revokeSystemPermission_result() {
    }

    public revokeSystemPermission_result(
      AccumuloException ouch1,
      AccumuloSecurityException ouch2)
    {
      this();
      this.ouch1 = ouch1;
      this.ouch2 = ouch2;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public revokeSystemPermission_result(revokeSystemPermission_result other) {
      if (other.isSetOuch1()) {
        this.ouch1 = new AccumuloException(other.ouch1);
      }
      if (other.isSetOuch2()) {
        this.ouch2 = new AccumuloSecurityException(other.ouch2);
      }
    }

    public revokeSystemPermission_result deepCopy() {
      return new revokeSystemPermission_result(this);
    }

    @Override
    public void clear() {
      this.ouch1 = null;
      this.ouch2 = null;
    }

    public AccumuloException getOuch1() {
      return this.ouch1;
    }

    public revokeSystemPermission_result setOuch1(AccumuloException ouch1) {
      this.ouch1 = ouch1;
      return this;
    }

    public void unsetOuch1() {
      this.ouch1 = null;
    }

    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch1() {
      return this.ouch1 != null;
    }

    public void setOuch1IsSet(boolean value) {
      if (!value) {
        this.ouch1 = null;
      }
    }

    public AccumuloSecurityException getOuch2() {
      return this.ouch2;
    }

    public revokeSystemPermission_result setOuch2(AccumuloSecurityException ouch2) {
      this.ouch2 = ouch2;
      return this;
    }

    public void unsetOuch2() {
      this.ouch2 = null;
    }

    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch2() {
      return this.ouch2 != null;
    }

    public void setOuch2IsSet(boolean value) {
      if (!value) {
        this.ouch2 = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case OUCH1:
        if (value == null) {
          unsetOuch1();
        } else {
          setOuch1((AccumuloException)value);
        }
        break;

      case OUCH2:
        if (value == null) {
          unsetOuch2();
        } else {
          setOuch2((AccumuloSecurityException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case OUCH1:
        return getOuch1();

      case OUCH2:
        return getOuch2();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case OUCH1:
        return isSetOuch1();
      case OUCH2:
        return isSetOuch2();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof revokeSystemPermission_result)
        return this.equals((revokeSystemPermission_result)that);
      return false;
    }

    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();
      if (this_present_ouch1 || that_present_ouch1) {
        if (!(this_present_ouch1 && that_present_ouch1))
          return false;
        if (!this.ouch1.equals(that.ouch1))
          return false;
      }

      boolean this_present_ouch2 = true && this.isSetOuch2();
      boolean that_present_ouch2 = true && that.isSetOuch2();
      if (this_present_ouch2 || that_present_ouch2) {
        if (!(this_present_ouch2 && that_present_ouch2))
          return false;
        if (!this.ouch2.equals(that.ouch2))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
      if (isSetOuch1())
        hashCode = hashCode * 8191 + ouch1.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
      if (isSetOuch2())
        hashCode = hashCode * 8191 + ouch2.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(revokeSystemPermission_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch1()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch2()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("revokeSystemPermission_result(");
      boolean first = true;

      sb.append("ouch1:");
      if (this.ouch1 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch1);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch2:");
      if (this.ouch2 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch2);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class revokeSystemPermission_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public revokeSystemPermission_resultStandardScheme getScheme() {
        return new revokeSystemPermission_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // OUCH1
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch1 = new AccumuloException();
                struct.ouch1.read(iprot);
                struct.setOuch1IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OUCH2
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch2 = new AccumuloSecurityException();
                struct.ouch2.read(iprot);
                struct.setOuch2IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, revokeSystemPermission_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.ouch1 != null) {
          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
          struct.ouch1.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch2 != null) {
          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
          struct.ouch2.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class revokeSystemPermission_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public revokeSystemPermission_resultTupleScheme getScheme() {
        return new revokeSystemPermission_resultTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetOuch2()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetOuch1()) {
          struct.ouch1.write(oprot);
        }
        if (struct.isSetOuch2()) {
          struct.ouch2.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, revokeSystemPermission_result struct) throws org.apache.thrift.TException {
        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);
          struct.setOuch1IsSet(true);
        }
        if (incoming.get(1)) {
          struct.ouch2 = new AccumuloSecurityException();
          struct.ouch2.read(iprot);
          struct.setOuch2IsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("revokeTablePermission_args");

    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField USER_FIELD_DESC = new org.apache.thrift.protocol.TField("user", org.apache.thrift.protocol.TType.STRING, (short)2);
    private static final org.apache.thrift.protocol.TField 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 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 java.nio.ByteBuffer login; // required
    public java.lang.String user; // required
    public java.lang.String table; // required
    /**
     * 
     * @see TablePermission
     */
    public TablePermission perm; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      LOGIN((short)1, "login"),
      USER((short)2, "user"),
      TABLE((short)3, "table"),
      /**
       * 
       * @see TablePermission
       */
      PERM((short)4, "perm");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // LOGIN
            return LOGIN;
          case 2: // USER
            return USER;
          case 3: // TABLE
            return TABLE;
          case 4: // PERM
            return PERM;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.TABLE, new org.apache.thrift.meta_data.FieldMetaData("table", 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, TablePermission.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(revokeTablePermission_args.class, metaDataMap);
    }

    public revokeTablePermission_args() {
    }

    public revokeTablePermission_args(
      java.nio.ByteBuffer login,
      java.lang.String user,
      java.lang.String table,
      TablePermission perm)
    {
      this();
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      this.user = user;
      this.table = table;
      this.perm = perm;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public revokeTablePermission_args(revokeTablePermission_args other) {
      if (other.isSetLogin()) {
        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
      }
      if (other.isSetUser()) {
        this.user = other.user;
      }
      if (other.isSetTable()) {
        this.table = other.table;
      }
      if (other.isSetPerm()) {
        this.perm = other.perm;
      }
    }

    public revokeTablePermission_args deepCopy() {
      return new revokeTablePermission_args(this);
    }

    @Override
    public void clear() {
      this.login = null;
      this.user = null;
      this.table = null;
      this.perm = null;
    }

    public byte[] getLogin() {
      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
      return login == null ? null : login.array();
    }

    public java.nio.ByteBuffer bufferForLogin() {
      return org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    public revokeTablePermission_args setLogin(byte[] login) {
      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
      return this;
    }

    public revokeTablePermission_args setLogin(java.nio.ByteBuffer login) {
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      return this;
    }

    public void unsetLogin() {
      this.login = null;
    }

    /** Returns true if field login is set (has been assigned a value) and false otherwise */
    public boolean isSetLogin() {
      return this.login != null;
    }

    public void setLoginIsSet(boolean value) {
      if (!value) {
        this.login = null;
      }
    }

    public java.lang.String getUser() {
      return this.user;
    }

    public revokeTablePermission_args setUser(java.lang.String user) {
      this.user = user;
      return this;
    }

    public void unsetUser() {
      this.user = null;
    }

    /** Returns true if field user is set (has been assigned a value) and false otherwise */
    public boolean isSetUser() {
      return this.user != null;
    }

    public void setUserIsSet(boolean value) {
      if (!value) {
        this.user = null;
      }
    }

    public java.lang.String getTable() {
      return this.table;
    }

    public revokeTablePermission_args setTable(java.lang.String table) {
      this.table = table;
      return this;
    }

    public void unsetTable() {
      this.table = null;
    }

    /** Returns true if field table is set (has been assigned a value) and false otherwise */
    public boolean isSetTable() {
      return this.table != null;
    }

    public void setTableIsSet(boolean value) {
      if (!value) {
        this.table = null;
      }
    }

    /**
     * 
     * @see TablePermission
     */
    public TablePermission getPerm() {
      return this.perm;
    }

    /**
     * 
     * @see TablePermission
     */
    public revokeTablePermission_args setPerm(TablePermission perm) {
      this.perm = perm;
      return this;
    }

    public void unsetPerm() {
      this.perm = null;
    }

    /** Returns true if field perm is set (has been assigned a value) and false otherwise */
    public boolean isSetPerm() {
      return this.perm != null;
    }

    public void setPermIsSet(boolean value) {
      if (!value) {
        this.perm = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case LOGIN:
        if (value == null) {
          unsetLogin();
        } else {
          if (value instanceof byte[]) {
            setLogin((byte[])value);
          } else {
            setLogin((java.nio.ByteBuffer)value);
          }
        }
        break;

      case USER:
        if (value == null) {
          unsetUser();
        } else {
          setUser((java.lang.String)value);
        }
        break;

      case TABLE:
        if (value == null) {
          unsetTable();
        } else {
          setTable((java.lang.String)value);
        }
        break;

      case PERM:
        if (value == null) {
          unsetPerm();
        } else {
          setPerm((TablePermission)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case LOGIN:
        return getLogin();

      case USER:
        return getUser();

      case TABLE:
        return getTable();

      case PERM:
        return getPerm();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case LOGIN:
        return isSetLogin();
      case USER:
        return isSetUser();
      case TABLE:
        return isSetTable();
      case PERM:
        return isSetPerm();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof revokeTablePermission_args)
        return this.equals((revokeTablePermission_args)that);
      return false;
    }

    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();
      if (this_present_login || that_present_login) {
        if (!(this_present_login && that_present_login))
          return false;
        if (!this.login.equals(that.login))
          return false;
      }

      boolean this_present_user = true && this.isSetUser();
      boolean that_present_user = true && that.isSetUser();
      if (this_present_user || that_present_user) {
        if (!(this_present_user && that_present_user))
          return false;
        if (!this.user.equals(that.user))
          return false;
      }

      boolean this_present_table = true && this.isSetTable();
      boolean that_present_table = true && that.isSetTable();
      if (this_present_table || that_present_table) {
        if (!(this_present_table && that_present_table))
          return false;
        if (!this.table.equals(that.table))
          return false;
      }

      boolean this_present_perm = true && this.isSetPerm();
      boolean that_present_perm = true && that.isSetPerm();
      if (this_present_perm || that_present_perm) {
        if (!(this_present_perm && that_present_perm))
          return false;
        if (!this.perm.equals(that.perm))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
      if (isSetLogin())
        hashCode = hashCode * 8191 + login.hashCode();

      hashCode = hashCode * 8191 + ((isSetUser()) ? 131071 : 524287);
      if (isSetUser())
        hashCode = hashCode * 8191 + user.hashCode();

      hashCode = hashCode * 8191 + ((isSetTable()) ? 131071 : 524287);
      if (isSetTable())
        hashCode = hashCode * 8191 + table.hashCode();

      hashCode = hashCode * 8191 + ((isSetPerm()) ? 131071 : 524287);
      if (isSetPerm())
        hashCode = hashCode * 8191 + perm.getValue();

      return hashCode;
    }

    @Override
    public int compareTo(revokeTablePermission_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLogin()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetUser()).compareTo(other.isSetUser());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetUser()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.user, other.user);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetTable()).compareTo(other.isSetTable());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetTable()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.table, other.table);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetPerm()).compareTo(other.isSetPerm());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetPerm()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.perm, other.perm);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("revokeTablePermission_args(");
      boolean first = true;

      sb.append("login:");
      if (this.login == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.login, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("user:");
      if (this.user == null) {
        sb.append("null");
      } else {
        sb.append(this.user);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("table:");
      if (this.table == null) {
        sb.append("null");
      } else {
        sb.append(this.table);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("perm:");
      if (this.perm == null) {
        sb.append("null");
      } else {
        sb.append(this.perm);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class revokeTablePermission_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public revokeTablePermission_argsStandardScheme getScheme() {
        return new revokeTablePermission_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // LOGIN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.login = iprot.readBinary();
                struct.setLoginIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // USER
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.user = iprot.readString();
                struct.setUserIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // TABLE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.table = iprot.readString();
                struct.setTableIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // PERM
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.perm = org.apache.accumulo.proxy.thrift.TablePermission.findByValue(iprot.readI32());
                struct.setPermIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, revokeTablePermission_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.login != null) {
          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
          oprot.writeBinary(struct.login);
          oprot.writeFieldEnd();
        }
        if (struct.user != null) {
          oprot.writeFieldBegin(USER_FIELD_DESC);
          oprot.writeString(struct.user);
          oprot.writeFieldEnd();
        }
        if (struct.table != null) {
          oprot.writeFieldBegin(TABLE_FIELD_DESC);
          oprot.writeString(struct.table);
          oprot.writeFieldEnd();
        }
        if (struct.perm != null) {
          oprot.writeFieldBegin(PERM_FIELD_DESC);
          oprot.writeI32(struct.perm.getValue());
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class revokeTablePermission_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public revokeTablePermission_argsTupleScheme getScheme() {
        return new revokeTablePermission_argsTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetUser()) {
          optionals.set(1);
        }
        if (struct.isSetTable()) {
          optionals.set(2);
        }
        if (struct.isSetPerm()) {
          optionals.set(3);
        }
        oprot.writeBitSet(optionals, 4);
        if (struct.isSetLogin()) {
          oprot.writeBinary(struct.login);
        }
        if (struct.isSetUser()) {
          oprot.writeString(struct.user);
        }
        if (struct.isSetTable()) {
          oprot.writeString(struct.table);
        }
        if (struct.isSetPerm()) {
          oprot.writeI32(struct.perm.getValue());
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, revokeTablePermission_args struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.user = iprot.readString();
          struct.setUserIsSet(true);
        }
        if (incoming.get(2)) {
          struct.table = iprot.readString();
          struct.setTableIsSet(true);
        }
        if (incoming.get(3)) {
          struct.perm = org.apache.accumulo.proxy.thrift.TablePermission.findByValue(iprot.readI32());
          struct.setPermIsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("revokeTablePermission_result");

    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField OUCH3_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch3", org.apache.thrift.protocol.TType.STRUCT, (short)3);

    private static final org.apache.thrift.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
    public TableNotFoundException ouch3; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      OUCH1((short)1, "ouch1"),
      OUCH2((short)2, "ouch2"),
      OUCH3((short)3, "ouch3");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // OUCH1
            return OUCH1;
          case 2: // OUCH2
            return OUCH2;
          case 3: // OUCH3
            return OUCH3;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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.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.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);
    }

    public revokeTablePermission_result() {
    }

    public revokeTablePermission_result(
      AccumuloException ouch1,
      AccumuloSecurityException ouch2,
      TableNotFoundException ouch3)
    {
      this();
      this.ouch1 = ouch1;
      this.ouch2 = ouch2;
      this.ouch3 = ouch3;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public revokeTablePermission_result(revokeTablePermission_result other) {
      if (other.isSetOuch1()) {
        this.ouch1 = new AccumuloException(other.ouch1);
      }
      if (other.isSetOuch2()) {
        this.ouch2 = new AccumuloSecurityException(other.ouch2);
      }
      if (other.isSetOuch3()) {
        this.ouch3 = new TableNotFoundException(other.ouch3);
      }
    }

    public revokeTablePermission_result deepCopy() {
      return new revokeTablePermission_result(this);
    }

    @Override
    public void clear() {
      this.ouch1 = null;
      this.ouch2 = null;
      this.ouch3 = null;
    }

    public AccumuloException getOuch1() {
      return this.ouch1;
    }

    public revokeTablePermission_result setOuch1(AccumuloException ouch1) {
      this.ouch1 = ouch1;
      return this;
    }

    public void unsetOuch1() {
      this.ouch1 = null;
    }

    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch1() {
      return this.ouch1 != null;
    }

    public void setOuch1IsSet(boolean value) {
      if (!value) {
        this.ouch1 = null;
      }
    }

    public AccumuloSecurityException getOuch2() {
      return this.ouch2;
    }

    public revokeTablePermission_result setOuch2(AccumuloSecurityException ouch2) {
      this.ouch2 = ouch2;
      return this;
    }

    public void unsetOuch2() {
      this.ouch2 = null;
    }

    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch2() {
      return this.ouch2 != null;
    }

    public void setOuch2IsSet(boolean value) {
      if (!value) {
        this.ouch2 = null;
      }
    }

    public TableNotFoundException getOuch3() {
      return this.ouch3;
    }

    public revokeTablePermission_result setOuch3(TableNotFoundException ouch3) {
      this.ouch3 = ouch3;
      return this;
    }

    public void unsetOuch3() {
      this.ouch3 = null;
    }

    /** Returns true if field ouch3 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch3() {
      return this.ouch3 != null;
    }

    public void setOuch3IsSet(boolean value) {
      if (!value) {
        this.ouch3 = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case OUCH1:
        if (value == null) {
          unsetOuch1();
        } else {
          setOuch1((AccumuloException)value);
        }
        break;

      case OUCH2:
        if (value == null) {
          unsetOuch2();
        } else {
          setOuch2((AccumuloSecurityException)value);
        }
        break;

      case OUCH3:
        if (value == null) {
          unsetOuch3();
        } else {
          setOuch3((TableNotFoundException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case OUCH1:
        return getOuch1();

      case OUCH2:
        return getOuch2();

      case OUCH3:
        return getOuch3();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case OUCH1:
        return isSetOuch1();
      case OUCH2:
        return isSetOuch2();
      case OUCH3:
        return isSetOuch3();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof revokeTablePermission_result)
        return this.equals((revokeTablePermission_result)that);
      return false;
    }

    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();
      if (this_present_ouch1 || that_present_ouch1) {
        if (!(this_present_ouch1 && that_present_ouch1))
          return false;
        if (!this.ouch1.equals(that.ouch1))
          return false;
      }

      boolean this_present_ouch2 = true && this.isSetOuch2();
      boolean that_present_ouch2 = true && that.isSetOuch2();
      if (this_present_ouch2 || that_present_ouch2) {
        if (!(this_present_ouch2 && that_present_ouch2))
          return false;
        if (!this.ouch2.equals(that.ouch2))
          return false;
      }

      boolean this_present_ouch3 = true && this.isSetOuch3();
      boolean that_present_ouch3 = true && that.isSetOuch3();
      if (this_present_ouch3 || that_present_ouch3) {
        if (!(this_present_ouch3 && that_present_ouch3))
          return false;
        if (!this.ouch3.equals(that.ouch3))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
      if (isSetOuch1())
        hashCode = hashCode * 8191 + ouch1.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
      if (isSetOuch2())
        hashCode = hashCode * 8191 + ouch2.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
      if (isSetOuch3())
        hashCode = hashCode * 8191 + ouch3.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(revokeTablePermission_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch1()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch2()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch3()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch3, other.ouch3);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("revokeTablePermission_result(");
      boolean first = true;

      sb.append("ouch1:");
      if (this.ouch1 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch1);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch2:");
      if (this.ouch2 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch2);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch3:");
      if (this.ouch3 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch3);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class revokeTablePermission_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public revokeTablePermission_resultStandardScheme getScheme() {
        return new revokeTablePermission_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // OUCH1
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch1 = new AccumuloException();
                struct.ouch1.read(iprot);
                struct.setOuch1IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OUCH2
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch2 = new AccumuloSecurityException();
                struct.ouch2.read(iprot);
                struct.setOuch2IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // OUCH3
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch3 = new TableNotFoundException();
                struct.ouch3.read(iprot);
                struct.setOuch3IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, revokeTablePermission_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.ouch1 != null) {
          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
          struct.ouch1.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch2 != null) {
          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
          struct.ouch2.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch3 != null) {
          oprot.writeFieldBegin(OUCH3_FIELD_DESC);
          struct.ouch3.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class revokeTablePermission_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public revokeTablePermission_resultTupleScheme getScheme() {
        return new revokeTablePermission_resultTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetOuch2()) {
          optionals.set(1);
        }
        if (struct.isSetOuch3()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetOuch1()) {
          struct.ouch1.write(oprot);
        }
        if (struct.isSetOuch2()) {
          struct.ouch2.write(oprot);
        }
        if (struct.isSetOuch3()) {
          struct.ouch3.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, revokeTablePermission_result struct) throws org.apache.thrift.TException {
        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);
          struct.setOuch1IsSet(true);
        }
        if (incoming.get(1)) {
          struct.ouch2 = new AccumuloSecurityException();
          struct.ouch2.read(iprot);
          struct.setOuch2IsSet(true);
        }
        if (incoming.get(2)) {
          struct.ouch3 = new TableNotFoundException();
          struct.ouch3.read(iprot);
          struct.setOuch3IsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("grantNamespacePermission_args");

    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField USER_FIELD_DESC = new org.apache.thrift.protocol.TField("user", org.apache.thrift.protocol.TType.STRING, (short)2);
    private static final org.apache.thrift.protocol.TField NAMESPACE_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("namespaceName", org.apache.thrift.protocol.TType.STRING, (short)3);
    private static final org.apache.thrift.protocol.TField PERM_FIELD_DESC = new org.apache.thrift.protocol.TField("perm", org.apache.thrift.protocol.TType.I32, (short)4);

    private static final 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 java.nio.ByteBuffer login; // required
    public java.lang.String user; // required
    public java.lang.String namespaceName; // required
    /**
     * 
     * @see NamespacePermission
     */
    public NamespacePermission perm; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      LOGIN((short)1, "login"),
      USER((short)2, "user"),
      NAMESPACE_NAME((short)3, "namespaceName"),
      /**
       * 
       * @see NamespacePermission
       */
      PERM((short)4, "perm");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // LOGIN
            return LOGIN;
          case 2: // USER
            return USER;
          case 3: // NAMESPACE_NAME
            return NAMESPACE_NAME;
          case 4: // PERM
            return PERM;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.NAMESPACE_NAME, new org.apache.thrift.meta_data.FieldMetaData("namespaceName", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.PERM, new org.apache.thrift.meta_data.FieldMetaData("perm", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, NamespacePermission.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(grantNamespacePermission_args.class, metaDataMap);
    }

    public grantNamespacePermission_args() {
    }

    public grantNamespacePermission_args(
      java.nio.ByteBuffer login,
      java.lang.String user,
      java.lang.String namespaceName,
      NamespacePermission perm)
    {
      this();
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      this.user = user;
      this.namespaceName = namespaceName;
      this.perm = perm;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public grantNamespacePermission_args(grantNamespacePermission_args other) {
      if (other.isSetLogin()) {
        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
      }
      if (other.isSetUser()) {
        this.user = other.user;
      }
      if (other.isSetNamespaceName()) {
        this.namespaceName = other.namespaceName;
      }
      if (other.isSetPerm()) {
        this.perm = other.perm;
      }
    }

    public grantNamespacePermission_args deepCopy() {
      return new grantNamespacePermission_args(this);
    }

    @Override
    public void clear() {
      this.login = null;
      this.user = null;
      this.namespaceName = null;
      this.perm = null;
    }

    public byte[] getLogin() {
      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
      return login == null ? null : login.array();
    }

    public java.nio.ByteBuffer bufferForLogin() {
      return org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    public grantNamespacePermission_args setLogin(byte[] login) {
      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
      return this;
    }

    public grantNamespacePermission_args setLogin(java.nio.ByteBuffer login) {
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      return this;
    }

    public void unsetLogin() {
      this.login = null;
    }

    /** Returns true if field login is set (has been assigned a value) and false otherwise */
    public boolean isSetLogin() {
      return this.login != null;
    }

    public void setLoginIsSet(boolean value) {
      if (!value) {
        this.login = null;
      }
    }

    public java.lang.String getUser() {
      return this.user;
    }

    public grantNamespacePermission_args setUser(java.lang.String user) {
      this.user = user;
      return this;
    }

    public void unsetUser() {
      this.user = null;
    }

    /** Returns true if field user is set (has been assigned a value) and false otherwise */
    public boolean isSetUser() {
      return this.user != null;
    }

    public void setUserIsSet(boolean value) {
      if (!value) {
        this.user = null;
      }
    }

    public java.lang.String getNamespaceName() {
      return this.namespaceName;
    }

    public grantNamespacePermission_args setNamespaceName(java.lang.String namespaceName) {
      this.namespaceName = namespaceName;
      return this;
    }

    public void unsetNamespaceName() {
      this.namespaceName = null;
    }

    /** Returns true if field namespaceName is set (has been assigned a value) and false otherwise */
    public boolean isSetNamespaceName() {
      return this.namespaceName != null;
    }

    public void setNamespaceNameIsSet(boolean value) {
      if (!value) {
        this.namespaceName = null;
      }
    }

    /**
     * 
     * @see NamespacePermission
     */
    public NamespacePermission getPerm() {
      return this.perm;
    }

    /**
     * 
     * @see NamespacePermission
     */
    public grantNamespacePermission_args setPerm(NamespacePermission perm) {
      this.perm = perm;
      return this;
    }

    public void unsetPerm() {
      this.perm = null;
    }

    /** Returns true if field perm is set (has been assigned a value) and false otherwise */
    public boolean isSetPerm() {
      return this.perm != null;
    }

    public void setPermIsSet(boolean value) {
      if (!value) {
        this.perm = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case LOGIN:
        if (value == null) {
          unsetLogin();
        } else {
          if (value instanceof byte[]) {
            setLogin((byte[])value);
          } else {
            setLogin((java.nio.ByteBuffer)value);
          }
        }
        break;

      case USER:
        if (value == null) {
          unsetUser();
        } else {
          setUser((java.lang.String)value);
        }
        break;

      case NAMESPACE_NAME:
        if (value == null) {
          unsetNamespaceName();
        } else {
          setNamespaceName((java.lang.String)value);
        }
        break;

      case PERM:
        if (value == null) {
          unsetPerm();
        } else {
          setPerm((NamespacePermission)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case LOGIN:
        return getLogin();

      case USER:
        return getUser();

      case NAMESPACE_NAME:
        return getNamespaceName();

      case PERM:
        return getPerm();

      }
      throw new 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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case LOGIN:
        return isSetLogin();
      case USER:
        return isSetUser();
      case NAMESPACE_NAME:
        return isSetNamespaceName();
      case PERM:
        return isSetPerm();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof grantNamespacePermission_args)
        return this.equals((grantNamespacePermission_args)that);
      return false;
    }

    public boolean equals(grantNamespacePermission_args that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_login = true && this.isSetLogin();
      boolean that_present_login = true && that.isSetLogin();
      if (this_present_login || that_present_login) {
        if (!(this_present_login && that_present_login))
          return false;
        if (!this.login.equals(that.login))
          return false;
      }

      boolean this_present_user = true && this.isSetUser();
      boolean that_present_user = true && that.isSetUser();
      if (this_present_user || that_present_user) {
        if (!(this_present_user && that_present_user))
          return false;
        if (!this.user.equals(that.user))
          return false;
      }

      boolean this_present_namespaceName = true && this.isSetNamespaceName();
      boolean that_present_namespaceName = true && that.isSetNamespaceName();
      if (this_present_namespaceName || that_present_namespaceName) {
        if (!(this_present_namespaceName && that_present_namespaceName))
          return false;
        if (!this.namespaceName.equals(that.namespaceName))
          return false;
      }

      boolean this_present_perm = true && this.isSetPerm();
      boolean that_present_perm = true && that.isSetPerm();
      if (this_present_perm || that_present_perm) {
        if (!(this_present_perm && that_present_perm))
          return false;
        if (!this.perm.equals(that.perm))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
      if (isSetLogin())
        hashCode = hashCode * 8191 + login.hashCode();

      hashCode = hashCode * 8191 + ((isSetUser()) ? 131071 : 524287);
      if (isSetUser())
        hashCode = hashCode * 8191 + user.hashCode();

      hashCode = hashCode * 8191 + ((isSetNamespaceName()) ? 131071 : 524287);
      if (isSetNamespaceName())
        hashCode = hashCode * 8191 + namespaceName.hashCode();

      hashCode = hashCode * 8191 + ((isSetPerm()) ? 131071 : 524287);
      if (isSetPerm())
        hashCode = hashCode * 8191 + perm.getValue();

      return hashCode;
    }

    @Override
    public int compareTo(grantNamespacePermission_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLogin()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetUser()).compareTo(other.isSetUser());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetUser()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.user, other.user);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetNamespaceName()).compareTo(other.isSetNamespaceName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetNamespaceName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.namespaceName, other.namespaceName);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetPerm()).compareTo(other.isSetPerm());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetPerm()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.perm, other.perm);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("grantNamespacePermission_args(");
      boolean first = true;

      sb.append("login:");
      if (this.login == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.login, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("user:");
      if (this.user == null) {
        sb.append("null");
      } else {
        sb.append(this.user);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("namespaceName:");
      if (this.namespaceName == null) {
        sb.append("null");
      } else {
        sb.append(this.namespaceName);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("perm:");
      if (this.perm == null) {
        sb.append("null");
      } else {
        sb.append(this.perm);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class grantNamespacePermission_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public grantNamespacePermission_argsStandardScheme getScheme() {
        return new grantNamespacePermission_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // LOGIN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.login = iprot.readBinary();
                struct.setLoginIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // USER
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.user = iprot.readString();
                struct.setUserIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // NAMESPACE_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.namespaceName = iprot.readString();
                struct.setNamespaceNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // PERM
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.perm = org.apache.accumulo.proxy.thrift.NamespacePermission.findByValue(iprot.readI32());
                struct.setPermIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, grantNamespacePermission_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.login != null) {
          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
          oprot.writeBinary(struct.login);
          oprot.writeFieldEnd();
        }
        if (struct.user != null) {
          oprot.writeFieldBegin(USER_FIELD_DESC);
          oprot.writeString(struct.user);
          oprot.writeFieldEnd();
        }
        if (struct.namespaceName != null) {
          oprot.writeFieldBegin(NAMESPACE_NAME_FIELD_DESC);
          oprot.writeString(struct.namespaceName);
          oprot.writeFieldEnd();
        }
        if (struct.perm != null) {
          oprot.writeFieldBegin(PERM_FIELD_DESC);
          oprot.writeI32(struct.perm.getValue());
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class grantNamespacePermission_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public grantNamespacePermission_argsTupleScheme getScheme() {
        return new grantNamespacePermission_argsTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetUser()) {
          optionals.set(1);
        }
        if (struct.isSetNamespaceName()) {
          optionals.set(2);
        }
        if (struct.isSetPerm()) {
          optionals.set(3);
        }
        oprot.writeBitSet(optionals, 4);
        if (struct.isSetLogin()) {
          oprot.writeBinary(struct.login);
        }
        if (struct.isSetUser()) {
          oprot.writeString(struct.user);
        }
        if (struct.isSetNamespaceName()) {
          oprot.writeString(struct.namespaceName);
        }
        if (struct.isSetPerm()) {
          oprot.writeI32(struct.perm.getValue());
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, grantNamespacePermission_args struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.user = iprot.readString();
          struct.setUserIsSet(true);
        }
        if (incoming.get(2)) {
          struct.namespaceName = iprot.readString();
          struct.setNamespaceNameIsSet(true);
        }
        if (incoming.get(3)) {
          struct.perm = org.apache.accumulo.proxy.thrift.NamespacePermission.findByValue(iprot.readI32());
          struct.setPermIsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("grantNamespacePermission_result");

    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);

    private static final 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

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      OUCH1((short)1, "ouch1"),
      OUCH2((short)2, "ouch2");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // OUCH1
            return OUCH1;
          case 2: // OUCH2
            return OUCH2;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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.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);
    }

    public grantNamespacePermission_result() {
    }

    public grantNamespacePermission_result(
      AccumuloException ouch1,
      AccumuloSecurityException ouch2)
    {
      this();
      this.ouch1 = ouch1;
      this.ouch2 = ouch2;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public grantNamespacePermission_result(grantNamespacePermission_result other) {
      if (other.isSetOuch1()) {
        this.ouch1 = new AccumuloException(other.ouch1);
      }
      if (other.isSetOuch2()) {
        this.ouch2 = new AccumuloSecurityException(other.ouch2);
      }
    }

    public grantNamespacePermission_result deepCopy() {
      return new grantNamespacePermission_result(this);
    }

    @Override
    public void clear() {
      this.ouch1 = null;
      this.ouch2 = null;
    }

    public AccumuloException getOuch1() {
      return this.ouch1;
    }

    public grantNamespacePermission_result setOuch1(AccumuloException ouch1) {
      this.ouch1 = ouch1;
      return this;
    }

    public void unsetOuch1() {
      this.ouch1 = null;
    }

    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch1() {
      return this.ouch1 != null;
    }

    public void setOuch1IsSet(boolean value) {
      if (!value) {
        this.ouch1 = null;
      }
    }

    public AccumuloSecurityException getOuch2() {
      return this.ouch2;
    }

    public grantNamespacePermission_result setOuch2(AccumuloSecurityException ouch2) {
      this.ouch2 = ouch2;
      return this;
    }

    public void unsetOuch2() {
      this.ouch2 = null;
    }

    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch2() {
      return this.ouch2 != null;
    }

    public void setOuch2IsSet(boolean value) {
      if (!value) {
        this.ouch2 = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case OUCH1:
        if (value == null) {
          unsetOuch1();
        } else {
          setOuch1((AccumuloException)value);
        }
        break;

      case OUCH2:
        if (value == null) {
          unsetOuch2();
        } else {
          setOuch2((AccumuloSecurityException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case OUCH1:
        return getOuch1();

      case OUCH2:
        return getOuch2();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case OUCH1:
        return isSetOuch1();
      case OUCH2:
        return isSetOuch2();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof grantNamespacePermission_result)
        return this.equals((grantNamespacePermission_result)that);
      return false;
    }

    public boolean equals(grantNamespacePermission_result that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_ouch1 = true && this.isSetOuch1();
      boolean that_present_ouch1 = true && that.isSetOuch1();
      if (this_present_ouch1 || that_present_ouch1) {
        if (!(this_present_ouch1 && that_present_ouch1))
          return false;
        if (!this.ouch1.equals(that.ouch1))
          return false;
      }

      boolean this_present_ouch2 = true && this.isSetOuch2();
      boolean that_present_ouch2 = true && that.isSetOuch2();
      if (this_present_ouch2 || that_present_ouch2) {
        if (!(this_present_ouch2 && that_present_ouch2))
          return false;
        if (!this.ouch2.equals(that.ouch2))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
      if (isSetOuch1())
        hashCode = hashCode * 8191 + ouch1.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
      if (isSetOuch2())
        hashCode = hashCode * 8191 + ouch2.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(grantNamespacePermission_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch1()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch2()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("grantNamespacePermission_result(");
      boolean first = true;

      sb.append("ouch1:");
      if (this.ouch1 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch1);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch2:");
      if (this.ouch2 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch2);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class grantNamespacePermission_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public grantNamespacePermission_resultStandardScheme getScheme() {
        return new grantNamespacePermission_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // OUCH1
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch1 = new AccumuloException();
                struct.ouch1.read(iprot);
                struct.setOuch1IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OUCH2
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch2 = new AccumuloSecurityException();
                struct.ouch2.read(iprot);
                struct.setOuch2IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, grantNamespacePermission_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.ouch1 != null) {
          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
          struct.ouch1.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch2 != null) {
          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
          struct.ouch2.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class grantNamespacePermission_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public grantNamespacePermission_resultTupleScheme getScheme() {
        return new grantNamespacePermission_resultTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetOuch2()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetOuch1()) {
          struct.ouch1.write(oprot);
        }
        if (struct.isSetOuch2()) {
          struct.ouch2.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, grantNamespacePermission_result struct) throws org.apache.thrift.TException {
        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);
          struct.setOuch1IsSet(true);
        }
        if (incoming.get(1)) {
          struct.ouch2 = new AccumuloSecurityException();
          struct.ouch2.read(iprot);
          struct.setOuch2IsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("hasNamespacePermission_args");

    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField USER_FIELD_DESC = new org.apache.thrift.protocol.TField("user", org.apache.thrift.protocol.TType.STRING, (short)2);
    private static final org.apache.thrift.protocol.TField NAMESPACE_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("namespaceName", org.apache.thrift.protocol.TType.STRING, (short)3);
    private static final org.apache.thrift.protocol.TField PERM_FIELD_DESC = new org.apache.thrift.protocol.TField("perm", org.apache.thrift.protocol.TType.I32, (short)4);

    private static final 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 java.nio.ByteBuffer login; // required
    public java.lang.String user; // required
    public java.lang.String namespaceName; // required
    /**
     * 
     * @see NamespacePermission
     */
    public NamespacePermission perm; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      LOGIN((short)1, "login"),
      USER((short)2, "user"),
      NAMESPACE_NAME((short)3, "namespaceName"),
      /**
       * 
       * @see NamespacePermission
       */
      PERM((short)4, "perm");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // LOGIN
            return LOGIN;
          case 2: // USER
            return USER;
          case 3: // NAMESPACE_NAME
            return NAMESPACE_NAME;
          case 4: // PERM
            return PERM;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.NAMESPACE_NAME, new org.apache.thrift.meta_data.FieldMetaData("namespaceName", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.PERM, new org.apache.thrift.meta_data.FieldMetaData("perm", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, NamespacePermission.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(hasNamespacePermission_args.class, metaDataMap);
    }

    public hasNamespacePermission_args() {
    }

    public hasNamespacePermission_args(
      java.nio.ByteBuffer login,
      java.lang.String user,
      java.lang.String namespaceName,
      NamespacePermission perm)
    {
      this();
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      this.user = user;
      this.namespaceName = namespaceName;
      this.perm = perm;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public hasNamespacePermission_args(hasNamespacePermission_args other) {
      if (other.isSetLogin()) {
        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
      }
      if (other.isSetUser()) {
        this.user = other.user;
      }
      if (other.isSetNamespaceName()) {
        this.namespaceName = other.namespaceName;
      }
      if (other.isSetPerm()) {
        this.perm = other.perm;
      }
    }

    public hasNamespacePermission_args deepCopy() {
      return new hasNamespacePermission_args(this);
    }

    @Override
    public void clear() {
      this.login = null;
      this.user = null;
      this.namespaceName = null;
      this.perm = null;
    }

    public byte[] getLogin() {
      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
      return login == null ? null : login.array();
    }

    public java.nio.ByteBuffer bufferForLogin() {
      return org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    public hasNamespacePermission_args setLogin(byte[] login) {
      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
      return this;
    }

    public hasNamespacePermission_args setLogin(java.nio.ByteBuffer login) {
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      return this;
    }

    public void unsetLogin() {
      this.login = null;
    }

    /** Returns true if field login is set (has been assigned a value) and false otherwise */
    public boolean isSetLogin() {
      return this.login != null;
    }

    public void setLoginIsSet(boolean value) {
      if (!value) {
        this.login = null;
      }
    }

    public java.lang.String getUser() {
      return this.user;
    }

    public hasNamespacePermission_args setUser(java.lang.String user) {
      this.user = user;
      return this;
    }

    public void unsetUser() {
      this.user = null;
    }

    /** Returns true if field user is set (has been assigned a value) and false otherwise */
    public boolean isSetUser() {
      return this.user != null;
    }

    public void setUserIsSet(boolean value) {
      if (!value) {
        this.user = null;
      }
    }

    public java.lang.String getNamespaceName() {
      return this.namespaceName;
    }

    public hasNamespacePermission_args setNamespaceName(java.lang.String namespaceName) {
      this.namespaceName = namespaceName;
      return this;
    }

    public void unsetNamespaceName() {
      this.namespaceName = null;
    }

    /** Returns true if field namespaceName is set (has been assigned a value) and false otherwise */
    public boolean isSetNamespaceName() {
      return this.namespaceName != null;
    }

    public void setNamespaceNameIsSet(boolean value) {
      if (!value) {
        this.namespaceName = null;
      }
    }

    /**
     * 
     * @see NamespacePermission
     */
    public NamespacePermission getPerm() {
      return this.perm;
    }

    /**
     * 
     * @see NamespacePermission
     */
    public hasNamespacePermission_args setPerm(NamespacePermission perm) {
      this.perm = perm;
      return this;
    }

    public void unsetPerm() {
      this.perm = null;
    }

    /** Returns true if field perm is set (has been assigned a value) and false otherwise */
    public boolean isSetPerm() {
      return this.perm != null;
    }

    public void setPermIsSet(boolean value) {
      if (!value) {
        this.perm = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case LOGIN:
        if (value == null) {
          unsetLogin();
        } else {
          if (value instanceof byte[]) {
            setLogin((byte[])value);
          } else {
            setLogin((java.nio.ByteBuffer)value);
          }
        }
        break;

      case USER:
        if (value == null) {
          unsetUser();
        } else {
          setUser((java.lang.String)value);
        }
        break;

      case NAMESPACE_NAME:
        if (value == null) {
          unsetNamespaceName();
        } else {
          setNamespaceName((java.lang.String)value);
        }
        break;

      case PERM:
        if (value == null) {
          unsetPerm();
        } else {
          setPerm((NamespacePermission)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case LOGIN:
        return getLogin();

      case USER:
        return getUser();

      case NAMESPACE_NAME:
        return getNamespaceName();

      case PERM:
        return getPerm();

      }
      throw new 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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case LOGIN:
        return isSetLogin();
      case USER:
        return isSetUser();
      case NAMESPACE_NAME:
        return isSetNamespaceName();
      case PERM:
        return isSetPerm();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof hasNamespacePermission_args)
        return this.equals((hasNamespacePermission_args)that);
      return false;
    }

    public boolean equals(hasNamespacePermission_args that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_login = true && this.isSetLogin();
      boolean that_present_login = true && that.isSetLogin();
      if (this_present_login || that_present_login) {
        if (!(this_present_login && that_present_login))
          return false;
        if (!this.login.equals(that.login))
          return false;
      }

      boolean this_present_user = true && this.isSetUser();
      boolean that_present_user = true && that.isSetUser();
      if (this_present_user || that_present_user) {
        if (!(this_present_user && that_present_user))
          return false;
        if (!this.user.equals(that.user))
          return false;
      }

      boolean this_present_namespaceName = true && this.isSetNamespaceName();
      boolean that_present_namespaceName = true && that.isSetNamespaceName();
      if (this_present_namespaceName || that_present_namespaceName) {
        if (!(this_present_namespaceName && that_present_namespaceName))
          return false;
        if (!this.namespaceName.equals(that.namespaceName))
          return false;
      }

      boolean this_present_perm = true && this.isSetPerm();
      boolean that_present_perm = true && that.isSetPerm();
      if (this_present_perm || that_present_perm) {
        if (!(this_present_perm && that_present_perm))
          return false;
        if (!this.perm.equals(that.perm))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
      if (isSetLogin())
        hashCode = hashCode * 8191 + login.hashCode();

      hashCode = hashCode * 8191 + ((isSetUser()) ? 131071 : 524287);
      if (isSetUser())
        hashCode = hashCode * 8191 + user.hashCode();

      hashCode = hashCode * 8191 + ((isSetNamespaceName()) ? 131071 : 524287);
      if (isSetNamespaceName())
        hashCode = hashCode * 8191 + namespaceName.hashCode();

      hashCode = hashCode * 8191 + ((isSetPerm()) ? 131071 : 524287);
      if (isSetPerm())
        hashCode = hashCode * 8191 + perm.getValue();

      return hashCode;
    }

    @Override
    public int compareTo(hasNamespacePermission_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLogin()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetUser()).compareTo(other.isSetUser());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetUser()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.user, other.user);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetNamespaceName()).compareTo(other.isSetNamespaceName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetNamespaceName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.namespaceName, other.namespaceName);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetPerm()).compareTo(other.isSetPerm());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetPerm()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.perm, other.perm);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("hasNamespacePermission_args(");
      boolean first = true;

      sb.append("login:");
      if (this.login == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.login, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("user:");
      if (this.user == null) {
        sb.append("null");
      } else {
        sb.append(this.user);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("namespaceName:");
      if (this.namespaceName == null) {
        sb.append("null");
      } else {
        sb.append(this.namespaceName);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("perm:");
      if (this.perm == null) {
        sb.append("null");
      } else {
        sb.append(this.perm);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class hasNamespacePermission_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public hasNamespacePermission_argsStandardScheme getScheme() {
        return new hasNamespacePermission_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // LOGIN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.login = iprot.readBinary();
                struct.setLoginIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // USER
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.user = iprot.readString();
                struct.setUserIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // NAMESPACE_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.namespaceName = iprot.readString();
                struct.setNamespaceNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // PERM
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.perm = org.apache.accumulo.proxy.thrift.NamespacePermission.findByValue(iprot.readI32());
                struct.setPermIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, hasNamespacePermission_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.login != null) {
          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
          oprot.writeBinary(struct.login);
          oprot.writeFieldEnd();
        }
        if (struct.user != null) {
          oprot.writeFieldBegin(USER_FIELD_DESC);
          oprot.writeString(struct.user);
          oprot.writeFieldEnd();
        }
        if (struct.namespaceName != null) {
          oprot.writeFieldBegin(NAMESPACE_NAME_FIELD_DESC);
          oprot.writeString(struct.namespaceName);
          oprot.writeFieldEnd();
        }
        if (struct.perm != null) {
          oprot.writeFieldBegin(PERM_FIELD_DESC);
          oprot.writeI32(struct.perm.getValue());
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class hasNamespacePermission_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public hasNamespacePermission_argsTupleScheme getScheme() {
        return new hasNamespacePermission_argsTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetUser()) {
          optionals.set(1);
        }
        if (struct.isSetNamespaceName()) {
          optionals.set(2);
        }
        if (struct.isSetPerm()) {
          optionals.set(3);
        }
        oprot.writeBitSet(optionals, 4);
        if (struct.isSetLogin()) {
          oprot.writeBinary(struct.login);
        }
        if (struct.isSetUser()) {
          oprot.writeString(struct.user);
        }
        if (struct.isSetNamespaceName()) {
          oprot.writeString(struct.namespaceName);
        }
        if (struct.isSetPerm()) {
          oprot.writeI32(struct.perm.getValue());
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, hasNamespacePermission_args struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.user = iprot.readString();
          struct.setUserIsSet(true);
        }
        if (incoming.get(2)) {
          struct.namespaceName = iprot.readString();
          struct.setNamespaceNameIsSet(true);
        }
        if (incoming.get(3)) {
          struct.perm = org.apache.accumulo.proxy.thrift.NamespacePermission.findByValue(iprot.readI32());
          struct.setPermIsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("hasNamespacePermission_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.BOOL, (short)0);
    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);

    private static final 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
    public AccumuloSecurityException ouch2; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      OUCH1((short)1, "ouch1"),
      OUCH2((short)2, "ouch2");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // OUCH1
            return OUCH1;
          case 2: // OUCH2
            return OUCH2;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __SUCCESS_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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.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);
    }

    public hasNamespacePermission_result() {
    }

    public hasNamespacePermission_result(
      boolean success,
      AccumuloException ouch1,
      AccumuloSecurityException ouch2)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
      this.ouch1 = ouch1;
      this.ouch2 = ouch2;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public hasNamespacePermission_result(hasNamespacePermission_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
      if (other.isSetOuch1()) {
        this.ouch1 = new AccumuloException(other.ouch1);
      }
      if (other.isSetOuch2()) {
        this.ouch2 = new AccumuloSecurityException(other.ouch2);
      }
    }

    public hasNamespacePermission_result deepCopy() {
      return new hasNamespacePermission_result(this);
    }

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
      this.ouch1 = null;
      this.ouch2 = null;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public hasNamespacePermission_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

    public void unsetSuccess() {
      __isset_bitfield = 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 org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    public void setSuccessIsSet(boolean value) {
      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
    }

    public AccumuloException getOuch1() {
      return this.ouch1;
    }

    public hasNamespacePermission_result setOuch1(AccumuloException ouch1) {
      this.ouch1 = ouch1;
      return this;
    }

    public void unsetOuch1() {
      this.ouch1 = null;
    }

    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch1() {
      return this.ouch1 != null;
    }

    public void setOuch1IsSet(boolean value) {
      if (!value) {
        this.ouch1 = null;
      }
    }

    public AccumuloSecurityException getOuch2() {
      return this.ouch2;
    }

    public hasNamespacePermission_result setOuch2(AccumuloSecurityException ouch2) {
      this.ouch2 = ouch2;
      return this;
    }

    public void unsetOuch2() {
      this.ouch2 = null;
    }

    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch2() {
      return this.ouch2 != null;
    }

    public void setOuch2IsSet(boolean value) {
      if (!value) {
        this.ouch2 = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.lang.Boolean)value);
        }
        break;

      case OUCH1:
        if (value == null) {
          unsetOuch1();
        } else {
          setOuch1((AccumuloException)value);
        }
        break;

      case OUCH2:
        if (value == null) {
          unsetOuch2();
        } else {
          setOuch2((AccumuloSecurityException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return isSuccess();

      case OUCH1:
        return getOuch1();

      case OUCH2:
        return getOuch2();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case OUCH1:
        return isSetOuch1();
      case OUCH2:
        return isSetOuch2();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof hasNamespacePermission_result)
        return this.equals((hasNamespacePermission_result)that);
      return false;
    }

    public boolean equals(hasNamespacePermission_result that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_success = true;
      boolean that_present_success = true;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      boolean this_present_ouch1 = true && this.isSetOuch1();
      boolean that_present_ouch1 = true && that.isSetOuch1();
      if (this_present_ouch1 || that_present_ouch1) {
        if (!(this_present_ouch1 && that_present_ouch1))
          return false;
        if (!this.ouch1.equals(that.ouch1))
          return false;
      }

      boolean this_present_ouch2 = true && this.isSetOuch2();
      boolean that_present_ouch2 = true && that.isSetOuch2();
      if (this_present_ouch2 || that_present_ouch2) {
        if (!(this_present_ouch2 && that_present_ouch2))
          return false;
        if (!this.ouch2.equals(that.ouch2))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((success) ? 131071 : 524287);

      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
      if (isSetOuch1())
        hashCode = hashCode * 8191 + ouch1.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
      if (isSetOuch2())
        hashCode = hashCode * 8191 + ouch2.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(hasNamespacePermission_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch1()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch2()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("hasNamespacePermission_result(");
      boolean first = true;

      sb.append("success:");
      sb.append(this.success);
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch1:");
      if (this.ouch1 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch1);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch2:");
      if (this.ouch2 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch2);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, 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;
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class hasNamespacePermission_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public hasNamespacePermission_resultStandardScheme getScheme() {
        return new hasNamespacePermission_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
                struct.success = iprot.readBool();
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // OUCH1
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch1 = new AccumuloException();
                struct.ouch1.read(iprot);
                struct.setOuch1IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OUCH2
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch2 = new AccumuloSecurityException();
                struct.ouch2.read(iprot);
                struct.setOuch2IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, hasNamespacePermission_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.isSetSuccess()) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          oprot.writeBool(struct.success);
          oprot.writeFieldEnd();
        }
        if (struct.ouch1 != null) {
          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
          struct.ouch1.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch2 != null) {
          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
          struct.ouch2.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class hasNamespacePermission_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public hasNamespacePermission_resultTupleScheme getScheme() {
        return new hasNamespacePermission_resultTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetOuch1()) {
          optionals.set(1);
        }
        if (struct.isSetOuch2()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
        if (struct.isSetOuch1()) {
          struct.ouch1.write(oprot);
        }
        if (struct.isSetOuch2()) {
          struct.ouch2.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, hasNamespacePermission_result struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.ouch1 = new AccumuloException();
          struct.ouch1.read(iprot);
          struct.setOuch1IsSet(true);
        }
        if (incoming.get(2)) {
          struct.ouch2 = new AccumuloSecurityException();
          struct.ouch2.read(iprot);
          struct.setOuch2IsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("revokeNamespacePermission_args");

    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField USER_FIELD_DESC = new org.apache.thrift.protocol.TField("user", org.apache.thrift.protocol.TType.STRING, (short)2);
    private static final org.apache.thrift.protocol.TField NAMESPACE_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("namespaceName", org.apache.thrift.protocol.TType.STRING, (short)3);
    private static final org.apache.thrift.protocol.TField PERM_FIELD_DESC = new org.apache.thrift.protocol.TField("perm", org.apache.thrift.protocol.TType.I32, (short)4);

    private static final 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 java.nio.ByteBuffer login; // required
    public java.lang.String user; // required
    public java.lang.String namespaceName; // required
    /**
     * 
     * @see NamespacePermission
     */
    public NamespacePermission perm; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      LOGIN((short)1, "login"),
      USER((short)2, "user"),
      NAMESPACE_NAME((short)3, "namespaceName"),
      /**
       * 
       * @see NamespacePermission
       */
      PERM((short)4, "perm");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // LOGIN
            return LOGIN;
          case 2: // USER
            return USER;
          case 3: // NAMESPACE_NAME
            return NAMESPACE_NAME;
          case 4: // PERM
            return PERM;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.NAMESPACE_NAME, new org.apache.thrift.meta_data.FieldMetaData("namespaceName", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.PERM, new org.apache.thrift.meta_data.FieldMetaData("perm", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, NamespacePermission.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(revokeNamespacePermission_args.class, metaDataMap);
    }

    public revokeNamespacePermission_args() {
    }

    public revokeNamespacePermission_args(
      java.nio.ByteBuffer login,
      java.lang.String user,
      java.lang.String namespaceName,
      NamespacePermission perm)
    {
      this();
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      this.user = user;
      this.namespaceName = namespaceName;
      this.perm = perm;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public revokeNamespacePermission_args(revokeNamespacePermission_args other) {
      if (other.isSetLogin()) {
        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
      }
      if (other.isSetUser()) {
        this.user = other.user;
      }
      if (other.isSetNamespaceName()) {
        this.namespaceName = other.namespaceName;
      }
      if (other.isSetPerm()) {
        this.perm = other.perm;
      }
    }

    public revokeNamespacePermission_args deepCopy() {
      return new revokeNamespacePermission_args(this);
    }

    @Override
    public void clear() {
      this.login = null;
      this.user = null;
      this.namespaceName = null;
      this.perm = null;
    }

    public byte[] getLogin() {
      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
      return login == null ? null : login.array();
    }

    public java.nio.ByteBuffer bufferForLogin() {
      return org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    public revokeNamespacePermission_args setLogin(byte[] login) {
      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
      return this;
    }

    public revokeNamespacePermission_args setLogin(java.nio.ByteBuffer login) {
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      return this;
    }

    public void unsetLogin() {
      this.login = null;
    }

    /** Returns true if field login is set (has been assigned a value) and false otherwise */
    public boolean isSetLogin() {
      return this.login != null;
    }

    public void setLoginIsSet(boolean value) {
      if (!value) {
        this.login = null;
      }
    }

    public java.lang.String getUser() {
      return this.user;
    }

    public revokeNamespacePermission_args setUser(java.lang.String user) {
      this.user = user;
      return this;
    }

    public void unsetUser() {
      this.user = null;
    }

    /** Returns true if field user is set (has been assigned a value) and false otherwise */
    public boolean isSetUser() {
      return this.user != null;
    }

    public void setUserIsSet(boolean value) {
      if (!value) {
        this.user = null;
      }
    }

    public java.lang.String getNamespaceName() {
      return this.namespaceName;
    }

    public revokeNamespacePermission_args setNamespaceName(java.lang.String namespaceName) {
      this.namespaceName = namespaceName;
      return this;
    }

    public void unsetNamespaceName() {
      this.namespaceName = null;
    }

    /** Returns true if field namespaceName is set (has been assigned a value) and false otherwise */
    public boolean isSetNamespaceName() {
      return this.namespaceName != null;
    }

    public void setNamespaceNameIsSet(boolean value) {
      if (!value) {
        this.namespaceName = null;
      }
    }

    /**
     * 
     * @see NamespacePermission
     */
    public NamespacePermission getPerm() {
      return this.perm;
    }

    /**
     * 
     * @see NamespacePermission
     */
    public revokeNamespacePermission_args setPerm(NamespacePermission perm) {
      this.perm = perm;
      return this;
    }

    public void unsetPerm() {
      this.perm = null;
    }

    /** Returns true if field perm is set (has been assigned a value) and false otherwise */
    public boolean isSetPerm() {
      return this.perm != null;
    }

    public void setPermIsSet(boolean value) {
      if (!value) {
        this.perm = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case LOGIN:
        if (value == null) {
          unsetLogin();
        } else {
          if (value instanceof byte[]) {
            setLogin((byte[])value);
          } else {
            setLogin((java.nio.ByteBuffer)value);
          }
        }
        break;

      case USER:
        if (value == null) {
          unsetUser();
        } else {
          setUser((java.lang.String)value);
        }
        break;

      case NAMESPACE_NAME:
        if (value == null) {
          unsetNamespaceName();
        } else {
          setNamespaceName((java.lang.String)value);
        }
        break;

      case PERM:
        if (value == null) {
          unsetPerm();
        } else {
          setPerm((NamespacePermission)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case LOGIN:
        return getLogin();

      case USER:
        return getUser();

      case NAMESPACE_NAME:
        return getNamespaceName();

      case PERM:
        return getPerm();

      }
      throw new 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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case LOGIN:
        return isSetLogin();
      case USER:
        return isSetUser();
      case NAMESPACE_NAME:
        return isSetNamespaceName();
      case PERM:
        return isSetPerm();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof revokeNamespacePermission_args)
        return this.equals((revokeNamespacePermission_args)that);
      return false;
    }

    public boolean equals(revokeNamespacePermission_args that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_login = true && this.isSetLogin();
      boolean that_present_login = true && that.isSetLogin();
      if (this_present_login || that_present_login) {
        if (!(this_present_login && that_present_login))
          return false;
        if (!this.login.equals(that.login))
          return false;
      }

      boolean this_present_user = true && this.isSetUser();
      boolean that_present_user = true && that.isSetUser();
      if (this_present_user || that_present_user) {
        if (!(this_present_user && that_present_user))
          return false;
        if (!this.user.equals(that.user))
          return false;
      }

      boolean this_present_namespaceName = true && this.isSetNamespaceName();
      boolean that_present_namespaceName = true && that.isSetNamespaceName();
      if (this_present_namespaceName || that_present_namespaceName) {
        if (!(this_present_namespaceName && that_present_namespaceName))
          return false;
        if (!this.namespaceName.equals(that.namespaceName))
          return false;
      }

      boolean this_present_perm = true && this.isSetPerm();
      boolean that_present_perm = true && that.isSetPerm();
      if (this_present_perm || that_present_perm) {
        if (!(this_present_perm && that_present_perm))
          return false;
        if (!this.perm.equals(that.perm))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
      if (isSetLogin())
        hashCode = hashCode * 8191 + login.hashCode();

      hashCode = hashCode * 8191 + ((isSetUser()) ? 131071 : 524287);
      if (isSetUser())
        hashCode = hashCode * 8191 + user.hashCode();

      hashCode = hashCode * 8191 + ((isSetNamespaceName()) ? 131071 : 524287);
      if (isSetNamespaceName())
        hashCode = hashCode * 8191 + namespaceName.hashCode();

      hashCode = hashCode * 8191 + ((isSetPerm()) ? 131071 : 524287);
      if (isSetPerm())
        hashCode = hashCode * 8191 + perm.getValue();

      return hashCode;
    }

    @Override
    public int compareTo(revokeNamespacePermission_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLogin()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetUser()).compareTo(other.isSetUser());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetUser()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.user, other.user);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetNamespaceName()).compareTo(other.isSetNamespaceName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetNamespaceName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.namespaceName, other.namespaceName);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetPerm()).compareTo(other.isSetPerm());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetPerm()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.perm, other.perm);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("revokeNamespacePermission_args(");
      boolean first = true;

      sb.append("login:");
      if (this.login == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.login, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("user:");
      if (this.user == null) {
        sb.append("null");
      } else {
        sb.append(this.user);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("namespaceName:");
      if (this.namespaceName == null) {
        sb.append("null");
      } else {
        sb.append(this.namespaceName);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("perm:");
      if (this.perm == null) {
        sb.append("null");
      } else {
        sb.append(this.perm);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class revokeNamespacePermission_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public revokeNamespacePermission_argsStandardScheme getScheme() {
        return new revokeNamespacePermission_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // LOGIN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.login = iprot.readBinary();
                struct.setLoginIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // USER
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.user = iprot.readString();
                struct.setUserIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // NAMESPACE_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.namespaceName = iprot.readString();
                struct.setNamespaceNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // PERM
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.perm = org.apache.accumulo.proxy.thrift.NamespacePermission.findByValue(iprot.readI32());
                struct.setPermIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, revokeNamespacePermission_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.login != null) {
          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
          oprot.writeBinary(struct.login);
          oprot.writeFieldEnd();
        }
        if (struct.user != null) {
          oprot.writeFieldBegin(USER_FIELD_DESC);
          oprot.writeString(struct.user);
          oprot.writeFieldEnd();
        }
        if (struct.namespaceName != null) {
          oprot.writeFieldBegin(NAMESPACE_NAME_FIELD_DESC);
          oprot.writeString(struct.namespaceName);
          oprot.writeFieldEnd();
        }
        if (struct.perm != null) {
          oprot.writeFieldBegin(PERM_FIELD_DESC);
          oprot.writeI32(struct.perm.getValue());
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class revokeNamespacePermission_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public revokeNamespacePermission_argsTupleScheme getScheme() {
        return new revokeNamespacePermission_argsTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetUser()) {
          optionals.set(1);
        }
        if (struct.isSetNamespaceName()) {
          optionals.set(2);
        }
        if (struct.isSetPerm()) {
          optionals.set(3);
        }
        oprot.writeBitSet(optionals, 4);
        if (struct.isSetLogin()) {
          oprot.writeBinary(struct.login);
        }
        if (struct.isSetUser()) {
          oprot.writeString(struct.user);
        }
        if (struct.isSetNamespaceName()) {
          oprot.writeString(struct.namespaceName);
        }
        if (struct.isSetPerm()) {
          oprot.writeI32(struct.perm.getValue());
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, revokeNamespacePermission_args struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.user = iprot.readString();
          struct.setUserIsSet(true);
        }
        if (incoming.get(2)) {
          struct.namespaceName = iprot.readString();
          struct.setNamespaceNameIsSet(true);
        }
        if (incoming.get(3)) {
          struct.perm = org.apache.accumulo.proxy.thrift.NamespacePermission.findByValue(iprot.readI32());
          struct.setPermIsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("revokeNamespacePermission_result");

    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);

    private static final 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

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      OUCH1((short)1, "ouch1"),
      OUCH2((short)2, "ouch2");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // OUCH1
            return OUCH1;
          case 2: // OUCH2
            return OUCH2;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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.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);
    }

    public revokeNamespacePermission_result() {
    }

    public revokeNamespacePermission_result(
      AccumuloException ouch1,
      AccumuloSecurityException ouch2)
    {
      this();
      this.ouch1 = ouch1;
      this.ouch2 = ouch2;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public revokeNamespacePermission_result(revokeNamespacePermission_result other) {
      if (other.isSetOuch1()) {
        this.ouch1 = new AccumuloException(other.ouch1);
      }
      if (other.isSetOuch2()) {
        this.ouch2 = new AccumuloSecurityException(other.ouch2);
      }
    }

    public revokeNamespacePermission_result deepCopy() {
      return new revokeNamespacePermission_result(this);
    }

    @Override
    public void clear() {
      this.ouch1 = null;
      this.ouch2 = null;
    }

    public AccumuloException getOuch1() {
      return this.ouch1;
    }

    public revokeNamespacePermission_result setOuch1(AccumuloException ouch1) {
      this.ouch1 = ouch1;
      return this;
    }

    public void unsetOuch1() {
      this.ouch1 = null;
    }

    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch1() {
      return this.ouch1 != null;
    }

    public void setOuch1IsSet(boolean value) {
      if (!value) {
        this.ouch1 = null;
      }
    }

    public AccumuloSecurityException getOuch2() {
      return this.ouch2;
    }

    public revokeNamespacePermission_result setOuch2(AccumuloSecurityException ouch2) {
      this.ouch2 = ouch2;
      return this;
    }

    public void unsetOuch2() {
      this.ouch2 = null;
    }

    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch2() {
      return this.ouch2 != null;
    }

    public void setOuch2IsSet(boolean value) {
      if (!value) {
        this.ouch2 = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case OUCH1:
        if (value == null) {
          unsetOuch1();
        } else {
          setOuch1((AccumuloException)value);
        }
        break;

      case OUCH2:
        if (value == null) {
          unsetOuch2();
        } else {
          setOuch2((AccumuloSecurityException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case OUCH1:
        return getOuch1();

      case OUCH2:
        return getOuch2();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case OUCH1:
        return isSetOuch1();
      case OUCH2:
        return isSetOuch2();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof revokeNamespacePermission_result)
        return this.equals((revokeNamespacePermission_result)that);
      return false;
    }

    public boolean equals(revokeNamespacePermission_result that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_ouch1 = true && this.isSetOuch1();
      boolean that_present_ouch1 = true && that.isSetOuch1();
      if (this_present_ouch1 || that_present_ouch1) {
        if (!(this_present_ouch1 && that_present_ouch1))
          return false;
        if (!this.ouch1.equals(that.ouch1))
          return false;
      }

      boolean this_present_ouch2 = true && this.isSetOuch2();
      boolean that_present_ouch2 = true && that.isSetOuch2();
      if (this_present_ouch2 || that_present_ouch2) {
        if (!(this_present_ouch2 && that_present_ouch2))
          return false;
        if (!this.ouch2.equals(that.ouch2))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
      if (isSetOuch1())
        hashCode = hashCode * 8191 + ouch1.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
      if (isSetOuch2())
        hashCode = hashCode * 8191 + ouch2.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(revokeNamespacePermission_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch1()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch2()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("revokeNamespacePermission_result(");
      boolean first = true;

      sb.append("ouch1:");
      if (this.ouch1 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch1);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch2:");
      if (this.ouch2 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch2);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class revokeNamespacePermission_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public revokeNamespacePermission_resultStandardScheme getScheme() {
        return new revokeNamespacePermission_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // OUCH1
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch1 = new AccumuloException();
                struct.ouch1.read(iprot);
                struct.setOuch1IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OUCH2
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch2 = new AccumuloSecurityException();
                struct.ouch2.read(iprot);
                struct.setOuch2IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, revokeNamespacePermission_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.ouch1 != null) {
          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
          struct.ouch1.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch2 != null) {
          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
          struct.ouch2.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class revokeNamespacePermission_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public revokeNamespacePermission_resultTupleScheme getScheme() {
        return new revokeNamespacePermission_resultTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetOuch2()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetOuch1()) {
          struct.ouch1.write(oprot);
        }
        if (struct.isSetOuch2()) {
          struct.ouch2.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, revokeNamespacePermission_result struct) throws org.apache.thrift.TException {
        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);
          struct.setOuch1IsSet(true);
        }
        if (incoming.get(1)) {
          struct.ouch2 = new AccumuloSecurityException();
          struct.ouch2.read(iprot);
          struct.setOuch2IsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("createBatchScanner_args");

    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField 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 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 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. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      LOGIN((short)1, "login"),
      TABLE_NAME((short)2, "tableName"),
      OPTIONS((short)3, "options");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // LOGIN
            return LOGIN;
          case 2: // TABLE_NAME
            return TABLE_NAME;
          case 3: // OPTIONS
            return OPTIONS;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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 = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(createBatchScanner_args.class, metaDataMap);
    }

    public createBatchScanner_args() {
    }

    public createBatchScanner_args(
      java.nio.ByteBuffer login,
      java.lang.String tableName,
      BatchScanOptions options)
    {
      this();
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      this.tableName = tableName;
      this.options = options;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public createBatchScanner_args(createBatchScanner_args other) {
      if (other.isSetLogin()) {
        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
      }
      if (other.isSetTableName()) {
        this.tableName = other.tableName;
      }
      if (other.isSetOptions()) {
        this.options = new BatchScanOptions(other.options);
      }
    }

    public createBatchScanner_args deepCopy() {
      return new createBatchScanner_args(this);
    }

    @Override
    public void clear() {
      this.login = null;
      this.tableName = null;
      this.options = null;
    }

    public byte[] getLogin() {
      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
      return login == null ? null : login.array();
    }

    public java.nio.ByteBuffer bufferForLogin() {
      return org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    public createBatchScanner_args setLogin(byte[] login) {
      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
      return this;
    }

    public createBatchScanner_args setLogin(java.nio.ByteBuffer login) {
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      return this;
    }

    public void unsetLogin() {
      this.login = null;
    }

    /** Returns true if field login is set (has been assigned a value) and false otherwise */
    public boolean isSetLogin() {
      return this.login != null;
    }

    public void setLoginIsSet(boolean value) {
      if (!value) {
        this.login = null;
      }
    }

    public java.lang.String getTableName() {
      return this.tableName;
    }

    public createBatchScanner_args setTableName(java.lang.String tableName) {
      this.tableName = tableName;
      return this;
    }

    public void unsetTableName() {
      this.tableName = null;
    }

    /** Returns true if field tableName is set (has been assigned a value) and false otherwise */
    public boolean isSetTableName() {
      return this.tableName != null;
    }

    public void setTableNameIsSet(boolean value) {
      if (!value) {
        this.tableName = null;
      }
    }

    public BatchScanOptions getOptions() {
      return this.options;
    }

    public createBatchScanner_args setOptions(BatchScanOptions options) {
      this.options = options;
      return this;
    }

    public void unsetOptions() {
      this.options = null;
    }

    /** Returns true if field options is set (has been assigned a value) and false otherwise */
    public boolean isSetOptions() {
      return this.options != null;
    }

    public void setOptionsIsSet(boolean value) {
      if (!value) {
        this.options = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case LOGIN:
        if (value == null) {
          unsetLogin();
        } else {
          if (value instanceof byte[]) {
            setLogin((byte[])value);
          } else {
            setLogin((java.nio.ByteBuffer)value);
          }
        }
        break;

      case TABLE_NAME:
        if (value == null) {
          unsetTableName();
        } else {
          setTableName((java.lang.String)value);
        }
        break;

      case OPTIONS:
        if (value == null) {
          unsetOptions();
        } else {
          setOptions((BatchScanOptions)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case LOGIN:
        return getLogin();

      case TABLE_NAME:
        return getTableName();

      case OPTIONS:
        return getOptions();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case LOGIN:
        return isSetLogin();
      case TABLE_NAME:
        return isSetTableName();
      case OPTIONS:
        return isSetOptions();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof createBatchScanner_args)
        return this.equals((createBatchScanner_args)that);
      return false;
    }

    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();
      if (this_present_login || that_present_login) {
        if (!(this_present_login && that_present_login))
          return false;
        if (!this.login.equals(that.login))
          return false;
      }

      boolean this_present_tableName = true && this.isSetTableName();
      boolean that_present_tableName = true && that.isSetTableName();
      if (this_present_tableName || that_present_tableName) {
        if (!(this_present_tableName && that_present_tableName))
          return false;
        if (!this.tableName.equals(that.tableName))
          return false;
      }

      boolean this_present_options = true && this.isSetOptions();
      boolean that_present_options = true && that.isSetOptions();
      if (this_present_options || that_present_options) {
        if (!(this_present_options && that_present_options))
          return false;
        if (!this.options.equals(that.options))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
      if (isSetLogin())
        hashCode = hashCode * 8191 + login.hashCode();

      hashCode = hashCode * 8191 + ((isSetTableName()) ? 131071 : 524287);
      if (isSetTableName())
        hashCode = hashCode * 8191 + tableName.hashCode();

      hashCode = hashCode * 8191 + ((isSetOptions()) ? 131071 : 524287);
      if (isSetOptions())
        hashCode = hashCode * 8191 + options.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(createBatchScanner_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLogin()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetTableName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.tableName, other.tableName);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOptions()).compareTo(other.isSetOptions());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOptions()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.options, other.options);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("createBatchScanner_args(");
      boolean first = true;

      sb.append("login:");
      if (this.login == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.login, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("tableName:");
      if (this.tableName == null) {
        sb.append("null");
      } else {
        sb.append(this.tableName);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("options:");
      if (this.options == null) {
        sb.append("null");
      } else {
        sb.append(this.options);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
      if (options != null) {
        options.validate();
      }
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class createBatchScanner_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public createBatchScanner_argsStandardScheme getScheme() {
        return new createBatchScanner_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // LOGIN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.login = iprot.readBinary();
                struct.setLoginIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // TABLE_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.tableName = iprot.readString();
                struct.setTableNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // OPTIONS
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.options = new BatchScanOptions();
                struct.options.read(iprot);
                struct.setOptionsIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, createBatchScanner_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.login != null) {
          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
          oprot.writeBinary(struct.login);
          oprot.writeFieldEnd();
        }
        if (struct.tableName != null) {
          oprot.writeFieldBegin(TABLE_NAME_FIELD_DESC);
          oprot.writeString(struct.tableName);
          oprot.writeFieldEnd();
        }
        if (struct.options != null) {
          oprot.writeFieldBegin(OPTIONS_FIELD_DESC);
          struct.options.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    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 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 {
        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);
        }
        if (struct.isSetTableName()) {
          optionals.set(1);
        }
        if (struct.isSetOptions()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetLogin()) {
          oprot.writeBinary(struct.login);
        }
        if (struct.isSetTableName()) {
          oprot.writeString(struct.tableName);
        }
        if (struct.isSetOptions()) {
          struct.options.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, createBatchScanner_args struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.tableName = iprot.readString();
          struct.setTableNameIsSet(true);
        }
        if (incoming.get(2)) {
          struct.options = new BatchScanOptions();
          struct.options.read(iprot);
          struct.setOptionsIsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("createBatchScanner_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.STRING, (short)0);
    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField OUCH3_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch3", org.apache.thrift.protocol.TType.STRUCT, (short)3);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new createBatchScanner_resultStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new createBatchScanner_resultTupleSchemeFactory();

    public java.lang.String success; // required
    public AccumuloException ouch1; // required
    public AccumuloSecurityException ouch2; // required
    public TableNotFoundException ouch3; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      OUCH1((short)1, "ouch1"),
      OUCH2((short)2, "ouch2"),
      OUCH3((short)3, "ouch3");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // OUCH1
            return OUCH1;
          case 2: // OUCH2
            return OUCH2;
          case 3: // OUCH3
            return OUCH3;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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.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.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);
    }

    public createBatchScanner_result() {
    }

    public createBatchScanner_result(
      java.lang.String success,
      AccumuloException ouch1,
      AccumuloSecurityException ouch2,
      TableNotFoundException ouch3)
    {
      this();
      this.success = success;
      this.ouch1 = ouch1;
      this.ouch2 = ouch2;
      this.ouch3 = ouch3;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public createBatchScanner_result(createBatchScanner_result other) {
      if (other.isSetSuccess()) {
        this.success = other.success;
      }
      if (other.isSetOuch1()) {
        this.ouch1 = new AccumuloException(other.ouch1);
      }
      if (other.isSetOuch2()) {
        this.ouch2 = new AccumuloSecurityException(other.ouch2);
      }
      if (other.isSetOuch3()) {
        this.ouch3 = new TableNotFoundException(other.ouch3);
      }
    }

    public createBatchScanner_result deepCopy() {
      return new createBatchScanner_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ouch1 = null;
      this.ouch2 = null;
      this.ouch3 = null;
    }

    public java.lang.String getSuccess() {
      return this.success;
    }

    public createBatchScanner_result setSuccess(java.lang.String success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return this.success != null;
    }

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public AccumuloException getOuch1() {
      return this.ouch1;
    }

    public createBatchScanner_result setOuch1(AccumuloException ouch1) {
      this.ouch1 = ouch1;
      return this;
    }

    public void unsetOuch1() {
      this.ouch1 = null;
    }

    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch1() {
      return this.ouch1 != null;
    }

    public void setOuch1IsSet(boolean value) {
      if (!value) {
        this.ouch1 = null;
      }
    }

    public AccumuloSecurityException getOuch2() {
      return this.ouch2;
    }

    public createBatchScanner_result setOuch2(AccumuloSecurityException ouch2) {
      this.ouch2 = ouch2;
      return this;
    }

    public void unsetOuch2() {
      this.ouch2 = null;
    }

    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch2() {
      return this.ouch2 != null;
    }

    public void setOuch2IsSet(boolean value) {
      if (!value) {
        this.ouch2 = null;
      }
    }

    public TableNotFoundException getOuch3() {
      return this.ouch3;
    }

    public createBatchScanner_result setOuch3(TableNotFoundException ouch3) {
      this.ouch3 = ouch3;
      return this;
    }

    public void unsetOuch3() {
      this.ouch3 = null;
    }

    /** Returns true if field ouch3 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch3() {
      return this.ouch3 != null;
    }

    public void setOuch3IsSet(boolean value) {
      if (!value) {
        this.ouch3 = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.lang.String)value);
        }
        break;

      case OUCH1:
        if (value == null) {
          unsetOuch1();
        } else {
          setOuch1((AccumuloException)value);
        }
        break;

      case OUCH2:
        if (value == null) {
          unsetOuch2();
        } else {
          setOuch2((AccumuloSecurityException)value);
        }
        break;

      case OUCH3:
        if (value == null) {
          unsetOuch3();
        } else {
          setOuch3((TableNotFoundException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case OUCH1:
        return getOuch1();

      case OUCH2:
        return getOuch2();

      case OUCH3:
        return getOuch3();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case OUCH1:
        return isSetOuch1();
      case OUCH2:
        return isSetOuch2();
      case OUCH3:
        return isSetOuch3();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof createBatchScanner_result)
        return this.equals((createBatchScanner_result)that);
      return false;
    }

    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();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ouch1 = true && this.isSetOuch1();
      boolean that_present_ouch1 = true && that.isSetOuch1();
      if (this_present_ouch1 || that_present_ouch1) {
        if (!(this_present_ouch1 && that_present_ouch1))
          return false;
        if (!this.ouch1.equals(that.ouch1))
          return false;
      }

      boolean this_present_ouch2 = true && this.isSetOuch2();
      boolean that_present_ouch2 = true && that.isSetOuch2();
      if (this_present_ouch2 || that_present_ouch2) {
        if (!(this_present_ouch2 && that_present_ouch2))
          return false;
        if (!this.ouch2.equals(that.ouch2))
          return false;
      }

      boolean this_present_ouch3 = true && this.isSetOuch3();
      boolean that_present_ouch3 = true && that.isSetOuch3();
      if (this_present_ouch3 || that_present_ouch3) {
        if (!(this_present_ouch3 && that_present_ouch3))
          return false;
        if (!this.ouch3.equals(that.ouch3))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
      if (isSetSuccess())
        hashCode = hashCode * 8191 + success.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
      if (isSetOuch1())
        hashCode = hashCode * 8191 + ouch1.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
      if (isSetOuch2())
        hashCode = hashCode * 8191 + ouch2.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
      if (isSetOuch3())
        hashCode = hashCode * 8191 + ouch3.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(createBatchScanner_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch1()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch2()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch3()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch3, other.ouch3);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("createBatchScanner_result(");
      boolean first = true;

      sb.append("success:");
      if (this.success == null) {
        sb.append("null");
      } else {
        sb.append(this.success);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch1:");
      if (this.ouch1 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch1);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch2:");
      if (this.ouch2 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch2);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch3:");
      if (this.ouch3 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch3);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class createBatchScanner_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public createBatchScanner_resultStandardScheme getScheme() {
        return new createBatchScanner_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.success = iprot.readString();
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // OUCH1
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch1 = new AccumuloException();
                struct.ouch1.read(iprot);
                struct.setOuch1IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OUCH2
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch2 = new AccumuloSecurityException();
                struct.ouch2.read(iprot);
                struct.setOuch2IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // OUCH3
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch3 = new TableNotFoundException();
                struct.ouch3.read(iprot);
                struct.setOuch3IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, createBatchScanner_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          oprot.writeString(struct.success);
          oprot.writeFieldEnd();
        }
        if (struct.ouch1 != null) {
          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
          struct.ouch1.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch2 != null) {
          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
          struct.ouch2.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch3 != null) {
          oprot.writeFieldBegin(OUCH3_FIELD_DESC);
          struct.ouch3.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class createBatchScanner_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public createBatchScanner_resultTupleScheme getScheme() {
        return new createBatchScanner_resultTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetOuch1()) {
          optionals.set(1);
        }
        if (struct.isSetOuch2()) {
          optionals.set(2);
        }
        if (struct.isSetOuch3()) {
          optionals.set(3);
        }
        oprot.writeBitSet(optionals, 4);
        if (struct.isSetSuccess()) {
          oprot.writeString(struct.success);
        }
        if (struct.isSetOuch1()) {
          struct.ouch1.write(oprot);
        }
        if (struct.isSetOuch2()) {
          struct.ouch2.write(oprot);
        }
        if (struct.isSetOuch3()) {
          struct.ouch3.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, createBatchScanner_result struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.ouch1 = new AccumuloException();
          struct.ouch1.read(iprot);
          struct.setOuch1IsSet(true);
        }
        if (incoming.get(2)) {
          struct.ouch2 = new AccumuloSecurityException();
          struct.ouch2.read(iprot);
          struct.setOuch2IsSet(true);
        }
        if (incoming.get(3)) {
          struct.ouch3 = new TableNotFoundException();
          struct.ouch3.read(iprot);
          struct.setOuch3IsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("createScanner_args");

    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField 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 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 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. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      LOGIN((short)1, "login"),
      TABLE_NAME((short)2, "tableName"),
      OPTIONS((short)3, "options");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // LOGIN
            return LOGIN;
          case 2: // TABLE_NAME
            return TABLE_NAME;
          case 3: // OPTIONS
            return OPTIONS;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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 = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(createScanner_args.class, metaDataMap);
    }

    public createScanner_args() {
    }

    public createScanner_args(
      java.nio.ByteBuffer login,
      java.lang.String tableName,
      ScanOptions options)
    {
      this();
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      this.tableName = tableName;
      this.options = options;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public createScanner_args(createScanner_args other) {
      if (other.isSetLogin()) {
        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
      }
      if (other.isSetTableName()) {
        this.tableName = other.tableName;
      }
      if (other.isSetOptions()) {
        this.options = new ScanOptions(other.options);
      }
    }

    public createScanner_args deepCopy() {
      return new createScanner_args(this);
    }

    @Override
    public void clear() {
      this.login = null;
      this.tableName = null;
      this.options = null;
    }

    public byte[] getLogin() {
      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
      return login == null ? null : login.array();
    }

    public java.nio.ByteBuffer bufferForLogin() {
      return org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    public createScanner_args setLogin(byte[] login) {
      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
      return this;
    }

    public createScanner_args setLogin(java.nio.ByteBuffer login) {
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      return this;
    }

    public void unsetLogin() {
      this.login = null;
    }

    /** Returns true if field login is set (has been assigned a value) and false otherwise */
    public boolean isSetLogin() {
      return this.login != null;
    }

    public void setLoginIsSet(boolean value) {
      if (!value) {
        this.login = null;
      }
    }

    public java.lang.String getTableName() {
      return this.tableName;
    }

    public createScanner_args setTableName(java.lang.String tableName) {
      this.tableName = tableName;
      return this;
    }

    public void unsetTableName() {
      this.tableName = null;
    }

    /** Returns true if field tableName is set (has been assigned a value) and false otherwise */
    public boolean isSetTableName() {
      return this.tableName != null;
    }

    public void setTableNameIsSet(boolean value) {
      if (!value) {
        this.tableName = null;
      }
    }

    public ScanOptions getOptions() {
      return this.options;
    }

    public createScanner_args setOptions(ScanOptions options) {
      this.options = options;
      return this;
    }

    public void unsetOptions() {
      this.options = null;
    }

    /** Returns true if field options is set (has been assigned a value) and false otherwise */
    public boolean isSetOptions() {
      return this.options != null;
    }

    public void setOptionsIsSet(boolean value) {
      if (!value) {
        this.options = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case LOGIN:
        if (value == null) {
          unsetLogin();
        } else {
          if (value instanceof byte[]) {
            setLogin((byte[])value);
          } else {
            setLogin((java.nio.ByteBuffer)value);
          }
        }
        break;

      case TABLE_NAME:
        if (value == null) {
          unsetTableName();
        } else {
          setTableName((java.lang.String)value);
        }
        break;

      case OPTIONS:
        if (value == null) {
          unsetOptions();
        } else {
          setOptions((ScanOptions)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case LOGIN:
        return getLogin();

      case TABLE_NAME:
        return getTableName();

      case OPTIONS:
        return getOptions();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case LOGIN:
        return isSetLogin();
      case TABLE_NAME:
        return isSetTableName();
      case OPTIONS:
        return isSetOptions();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof createScanner_args)
        return this.equals((createScanner_args)that);
      return false;
    }

    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();
      if (this_present_login || that_present_login) {
        if (!(this_present_login && that_present_login))
          return false;
        if (!this.login.equals(that.login))
          return false;
      }

      boolean this_present_tableName = true && this.isSetTableName();
      boolean that_present_tableName = true && that.isSetTableName();
      if (this_present_tableName || that_present_tableName) {
        if (!(this_present_tableName && that_present_tableName))
          return false;
        if (!this.tableName.equals(that.tableName))
          return false;
      }

      boolean this_present_options = true && this.isSetOptions();
      boolean that_present_options = true && that.isSetOptions();
      if (this_present_options || that_present_options) {
        if (!(this_present_options && that_present_options))
          return false;
        if (!this.options.equals(that.options))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
      if (isSetLogin())
        hashCode = hashCode * 8191 + login.hashCode();

      hashCode = hashCode * 8191 + ((isSetTableName()) ? 131071 : 524287);
      if (isSetTableName())
        hashCode = hashCode * 8191 + tableName.hashCode();

      hashCode = hashCode * 8191 + ((isSetOptions()) ? 131071 : 524287);
      if (isSetOptions())
        hashCode = hashCode * 8191 + options.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(createScanner_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLogin()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetTableName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.tableName, other.tableName);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOptions()).compareTo(other.isSetOptions());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOptions()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.options, other.options);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("createScanner_args(");
      boolean first = true;

      sb.append("login:");
      if (this.login == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.login, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("tableName:");
      if (this.tableName == null) {
        sb.append("null");
      } else {
        sb.append(this.tableName);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("options:");
      if (this.options == null) {
        sb.append("null");
      } else {
        sb.append(this.options);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
      if (options != null) {
        options.validate();
      }
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class createScanner_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public createScanner_argsStandardScheme getScheme() {
        return new createScanner_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // LOGIN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.login = iprot.readBinary();
                struct.setLoginIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // TABLE_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.tableName = iprot.readString();
                struct.setTableNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // OPTIONS
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.options = new ScanOptions();
                struct.options.read(iprot);
                struct.setOptionsIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, createScanner_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.login != null) {
          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
          oprot.writeBinary(struct.login);
          oprot.writeFieldEnd();
        }
        if (struct.tableName != null) {
          oprot.writeFieldBegin(TABLE_NAME_FIELD_DESC);
          oprot.writeString(struct.tableName);
          oprot.writeFieldEnd();
        }
        if (struct.options != null) {
          oprot.writeFieldBegin(OPTIONS_FIELD_DESC);
          struct.options.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    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 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 {
        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);
        }
        if (struct.isSetTableName()) {
          optionals.set(1);
        }
        if (struct.isSetOptions()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetLogin()) {
          oprot.writeBinary(struct.login);
        }
        if (struct.isSetTableName()) {
          oprot.writeString(struct.tableName);
        }
        if (struct.isSetOptions()) {
          struct.options.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, createScanner_args struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.tableName = iprot.readString();
          struct.setTableNameIsSet(true);
        }
        if (incoming.get(2)) {
          struct.options = new ScanOptions();
          struct.options.read(iprot);
          struct.setOptionsIsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("createScanner_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.STRING, (short)0);
    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField OUCH3_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch3", org.apache.thrift.protocol.TType.STRUCT, (short)3);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new createScanner_resultStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new createScanner_resultTupleSchemeFactory();

    public java.lang.String success; // required
    public AccumuloException ouch1; // required
    public AccumuloSecurityException ouch2; // required
    public TableNotFoundException ouch3; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      OUCH1((short)1, "ouch1"),
      OUCH2((short)2, "ouch2"),
      OUCH3((short)3, "ouch3");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // OUCH1
            return OUCH1;
          case 2: // OUCH2
            return OUCH2;
          case 3: // OUCH3
            return OUCH3;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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.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.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);
    }

    public createScanner_result() {
    }

    public createScanner_result(
      java.lang.String success,
      AccumuloException ouch1,
      AccumuloSecurityException ouch2,
      TableNotFoundException ouch3)
    {
      this();
      this.success = success;
      this.ouch1 = ouch1;
      this.ouch2 = ouch2;
      this.ouch3 = ouch3;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public createScanner_result(createScanner_result other) {
      if (other.isSetSuccess()) {
        this.success = other.success;
      }
      if (other.isSetOuch1()) {
        this.ouch1 = new AccumuloException(other.ouch1);
      }
      if (other.isSetOuch2()) {
        this.ouch2 = new AccumuloSecurityException(other.ouch2);
      }
      if (other.isSetOuch3()) {
        this.ouch3 = new TableNotFoundException(other.ouch3);
      }
    }

    public createScanner_result deepCopy() {
      return new createScanner_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ouch1 = null;
      this.ouch2 = null;
      this.ouch3 = null;
    }

    public java.lang.String getSuccess() {
      return this.success;
    }

    public createScanner_result setSuccess(java.lang.String success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return this.success != null;
    }

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public AccumuloException getOuch1() {
      return this.ouch1;
    }

    public createScanner_result setOuch1(AccumuloException ouch1) {
      this.ouch1 = ouch1;
      return this;
    }

    public void unsetOuch1() {
      this.ouch1 = null;
    }

    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch1() {
      return this.ouch1 != null;
    }

    public void setOuch1IsSet(boolean value) {
      if (!value) {
        this.ouch1 = null;
      }
    }

    public AccumuloSecurityException getOuch2() {
      return this.ouch2;
    }

    public createScanner_result setOuch2(AccumuloSecurityException ouch2) {
      this.ouch2 = ouch2;
      return this;
    }

    public void unsetOuch2() {
      this.ouch2 = null;
    }

    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch2() {
      return this.ouch2 != null;
    }

    public void setOuch2IsSet(boolean value) {
      if (!value) {
        this.ouch2 = null;
      }
    }

    public TableNotFoundException getOuch3() {
      return this.ouch3;
    }

    public createScanner_result setOuch3(TableNotFoundException ouch3) {
      this.ouch3 = ouch3;
      return this;
    }

    public void unsetOuch3() {
      this.ouch3 = null;
    }

    /** Returns true if field ouch3 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch3() {
      return this.ouch3 != null;
    }

    public void setOuch3IsSet(boolean value) {
      if (!value) {
        this.ouch3 = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.lang.String)value);
        }
        break;

      case OUCH1:
        if (value == null) {
          unsetOuch1();
        } else {
          setOuch1((AccumuloException)value);
        }
        break;

      case OUCH2:
        if (value == null) {
          unsetOuch2();
        } else {
          setOuch2((AccumuloSecurityException)value);
        }
        break;

      case OUCH3:
        if (value == null) {
          unsetOuch3();
        } else {
          setOuch3((TableNotFoundException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case OUCH1:
        return getOuch1();

      case OUCH2:
        return getOuch2();

      case OUCH3:
        return getOuch3();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case OUCH1:
        return isSetOuch1();
      case OUCH2:
        return isSetOuch2();
      case OUCH3:
        return isSetOuch3();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof createScanner_result)
        return this.equals((createScanner_result)that);
      return false;
    }

    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();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ouch1 = true && this.isSetOuch1();
      boolean that_present_ouch1 = true && that.isSetOuch1();
      if (this_present_ouch1 || that_present_ouch1) {
        if (!(this_present_ouch1 && that_present_ouch1))
          return false;
        if (!this.ouch1.equals(that.ouch1))
          return false;
      }

      boolean this_present_ouch2 = true && this.isSetOuch2();
      boolean that_present_ouch2 = true && that.isSetOuch2();
      if (this_present_ouch2 || that_present_ouch2) {
        if (!(this_present_ouch2 && that_present_ouch2))
          return false;
        if (!this.ouch2.equals(that.ouch2))
          return false;
      }

      boolean this_present_ouch3 = true && this.isSetOuch3();
      boolean that_present_ouch3 = true && that.isSetOuch3();
      if (this_present_ouch3 || that_present_ouch3) {
        if (!(this_present_ouch3 && that_present_ouch3))
          return false;
        if (!this.ouch3.equals(that.ouch3))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
      if (isSetSuccess())
        hashCode = hashCode * 8191 + success.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
      if (isSetOuch1())
        hashCode = hashCode * 8191 + ouch1.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
      if (isSetOuch2())
        hashCode = hashCode * 8191 + ouch2.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
      if (isSetOuch3())
        hashCode = hashCode * 8191 + ouch3.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(createScanner_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch1()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch2()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch3()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch3, other.ouch3);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("createScanner_result(");
      boolean first = true;

      sb.append("success:");
      if (this.success == null) {
        sb.append("null");
      } else {
        sb.append(this.success);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch1:");
      if (this.ouch1 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch1);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch2:");
      if (this.ouch2 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch2);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch3:");
      if (this.ouch3 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch3);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class createScanner_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public createScanner_resultStandardScheme getScheme() {
        return new createScanner_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.success = iprot.readString();
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // OUCH1
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch1 = new AccumuloException();
                struct.ouch1.read(iprot);
                struct.setOuch1IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OUCH2
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch2 = new AccumuloSecurityException();
                struct.ouch2.read(iprot);
                struct.setOuch2IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // OUCH3
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch3 = new TableNotFoundException();
                struct.ouch3.read(iprot);
                struct.setOuch3IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, createScanner_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          oprot.writeString(struct.success);
          oprot.writeFieldEnd();
        }
        if (struct.ouch1 != null) {
          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
          struct.ouch1.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch2 != null) {
          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
          struct.ouch2.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch3 != null) {
          oprot.writeFieldBegin(OUCH3_FIELD_DESC);
          struct.ouch3.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class createScanner_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public createScanner_resultTupleScheme getScheme() {
        return new createScanner_resultTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetOuch1()) {
          optionals.set(1);
        }
        if (struct.isSetOuch2()) {
          optionals.set(2);
        }
        if (struct.isSetOuch3()) {
          optionals.set(3);
        }
        oprot.writeBitSet(optionals, 4);
        if (struct.isSetSuccess()) {
          oprot.writeString(struct.success);
        }
        if (struct.isSetOuch1()) {
          struct.ouch1.write(oprot);
        }
        if (struct.isSetOuch2()) {
          struct.ouch2.write(oprot);
        }
        if (struct.isSetOuch3()) {
          struct.ouch3.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, createScanner_result struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.ouch1 = new AccumuloException();
          struct.ouch1.read(iprot);
          struct.setOuch1IsSet(true);
        }
        if (incoming.get(2)) {
          struct.ouch2 = new AccumuloSecurityException();
          struct.ouch2.read(iprot);
          struct.setOuch2IsSet(true);
        }
        if (incoming.get(3)) {
          struct.ouch3 = new TableNotFoundException();
          struct.ouch3.read(iprot);
          struct.setOuch3IsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("hasNext_args");

    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.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new hasNext_argsStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new hasNext_argsTupleSchemeFactory();

    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 java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // SCANNER
            return SCANNER;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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 = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(hasNext_args.class, metaDataMap);
    }

    public hasNext_args() {
    }

    public hasNext_args(
      java.lang.String scanner)
    {
      this();
      this.scanner = scanner;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public hasNext_args(hasNext_args other) {
      if (other.isSetScanner()) {
        this.scanner = other.scanner;
      }
    }

    public hasNext_args deepCopy() {
      return new hasNext_args(this);
    }

    @Override
    public void clear() {
      this.scanner = null;
    }

    public java.lang.String getScanner() {
      return this.scanner;
    }

    public hasNext_args setScanner(java.lang.String scanner) {
      this.scanner = scanner;
      return this;
    }

    public void unsetScanner() {
      this.scanner = null;
    }

    /** Returns true if field scanner is set (has been assigned a value) and false otherwise */
    public boolean isSetScanner() {
      return this.scanner != null;
    }

    public void setScannerIsSet(boolean value) {
      if (!value) {
        this.scanner = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SCANNER:
        if (value == null) {
          unsetScanner();
        } else {
          setScanner((java.lang.String)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SCANNER:
        return getScanner();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SCANNER:
        return isSetScanner();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof hasNext_args)
        return this.equals((hasNext_args)that);
      return false;
    }

    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();
      if (this_present_scanner || that_present_scanner) {
        if (!(this_present_scanner && that_present_scanner))
          return false;
        if (!this.scanner.equals(that.scanner))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetScanner()) ? 131071 : 524287);
      if (isSetScanner())
        hashCode = hashCode * 8191 + scanner.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(hasNext_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetScanner()).compareTo(other.isSetScanner());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetScanner()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.scanner, other.scanner);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("hasNext_args(");
      boolean first = true;

      sb.append("scanner:");
      if (this.scanner == null) {
        sb.append("null");
      } else {
        sb.append(this.scanner);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class hasNext_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public hasNext_argsStandardScheme getScheme() {
        return new hasNext_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // SCANNER
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.scanner = iprot.readString();
                struct.setScannerIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, hasNext_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.scanner != null) {
          oprot.writeFieldBegin(SCANNER_FIELD_DESC);
          oprot.writeString(struct.scanner);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    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 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 {
        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);
        }
        oprot.writeBitSet(optionals, 1);
        if (struct.isSetScanner()) {
          oprot.writeString(struct.scanner);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, hasNext_args struct) throws org.apache.thrift.TException {
        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);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("hasNext_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.BOOL, (short)0);
    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);

    private static final org.apache.thrift.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

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      OUCH1((short)1, "ouch1");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // OUCH1
            return OUCH1;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __SUCCESS_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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);
    }

    public hasNext_result() {
    }

    public hasNext_result(
      boolean success,
      UnknownScanner ouch1)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
      this.ouch1 = ouch1;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public hasNext_result(hasNext_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
      if (other.isSetOuch1()) {
        this.ouch1 = new UnknownScanner(other.ouch1);
      }
    }

    public hasNext_result deepCopy() {
      return new hasNext_result(this);
    }

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
      this.ouch1 = null;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public hasNext_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

    public void unsetSuccess() {
      __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 org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    public void setSuccessIsSet(boolean value) {
      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
    }

    public UnknownScanner getOuch1() {
      return this.ouch1;
    }

    public hasNext_result setOuch1(UnknownScanner ouch1) {
      this.ouch1 = ouch1;
      return this;
    }

    public void unsetOuch1() {
      this.ouch1 = null;
    }

    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch1() {
      return this.ouch1 != null;
    }

    public void setOuch1IsSet(boolean value) {
      if (!value) {
        this.ouch1 = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.lang.Boolean)value);
        }
        break;

      case OUCH1:
        if (value == null) {
          unsetOuch1();
        } else {
          setOuch1((UnknownScanner)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return isSuccess();

      case OUCH1:
        return getOuch1();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case OUCH1:
        return isSetOuch1();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof hasNext_result)
        return this.equals((hasNext_result)that);
      return false;
    }

    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;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      boolean this_present_ouch1 = true && this.isSetOuch1();
      boolean that_present_ouch1 = true && that.isSetOuch1();
      if (this_present_ouch1 || that_present_ouch1) {
        if (!(this_present_ouch1 && that_present_ouch1))
          return false;
        if (!this.ouch1.equals(that.ouch1))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((success) ? 131071 : 524287);

      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
      if (isSetOuch1())
        hashCode = hashCode * 8191 + ouch1.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(hasNext_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch1()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("hasNext_result(");
      boolean first = true;

      sb.append("success:");
      sb.append(this.success);
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch1:");
      if (this.ouch1 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch1);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, 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;
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class hasNext_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public hasNext_resultStandardScheme getScheme() {
        return new hasNext_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
                struct.success = iprot.readBool();
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // OUCH1
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch1 = new UnknownScanner();
                struct.ouch1.read(iprot);
                struct.setOuch1IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, hasNext_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.isSetSuccess()) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          oprot.writeBool(struct.success);
          oprot.writeFieldEnd();
        }
        if (struct.ouch1 != null) {
          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
          struct.ouch1.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    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 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 {
        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);
        }
        if (struct.isSetOuch1()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
        if (struct.isSetOuch1()) {
          struct.ouch1.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, hasNext_result struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.ouch1 = new UnknownScanner();
          struct.ouch1.read(iprot);
          struct.setOuch1IsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("nextEntry_args");

    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.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new nextEntry_argsStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new nextEntry_argsTupleSchemeFactory();

    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 java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // SCANNER
            return SCANNER;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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 = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(nextEntry_args.class, metaDataMap);
    }

    public nextEntry_args() {
    }

    public nextEntry_args(
      java.lang.String scanner)
    {
      this();
      this.scanner = scanner;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public nextEntry_args(nextEntry_args other) {
      if (other.isSetScanner()) {
        this.scanner = other.scanner;
      }
    }

    public nextEntry_args deepCopy() {
      return new nextEntry_args(this);
    }

    @Override
    public void clear() {
      this.scanner = null;
    }

    public java.lang.String getScanner() {
      return this.scanner;
    }

    public nextEntry_args setScanner(java.lang.String scanner) {
      this.scanner = scanner;
      return this;
    }

    public void unsetScanner() {
      this.scanner = null;
    }

    /** Returns true if field scanner is set (has been assigned a value) and false otherwise */
    public boolean isSetScanner() {
      return this.scanner != null;
    }

    public void setScannerIsSet(boolean value) {
      if (!value) {
        this.scanner = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SCANNER:
        if (value == null) {
          unsetScanner();
        } else {
          setScanner((java.lang.String)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SCANNER:
        return getScanner();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SCANNER:
        return isSetScanner();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof nextEntry_args)
        return this.equals((nextEntry_args)that);
      return false;
    }

    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();
      if (this_present_scanner || that_present_scanner) {
        if (!(this_present_scanner && that_present_scanner))
          return false;
        if (!this.scanner.equals(that.scanner))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetScanner()) ? 131071 : 524287);
      if (isSetScanner())
        hashCode = hashCode * 8191 + scanner.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(nextEntry_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetScanner()).compareTo(other.isSetScanner());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetScanner()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.scanner, other.scanner);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("nextEntry_args(");
      boolean first = true;

      sb.append("scanner:");
      if (this.scanner == null) {
        sb.append("null");
      } else {
        sb.append(this.scanner);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class nextEntry_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public nextEntry_argsStandardScheme getScheme() {
        return new nextEntry_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // SCANNER
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.scanner = iprot.readString();
                struct.setScannerIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, nextEntry_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.scanner != null) {
          oprot.writeFieldBegin(SCANNER_FIELD_DESC);
          oprot.writeString(struct.scanner);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    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 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 {
        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);
        }
        oprot.writeBitSet(optionals, 1);
        if (struct.isSetScanner()) {
          oprot.writeString(struct.scanner);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, nextEntry_args struct) throws org.apache.thrift.TException {
        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);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("nextEntry_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.STRUCT, (short)0);
    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField OUCH3_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch3", org.apache.thrift.protocol.TType.STRUCT, (short)3);

    private static final 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
    public UnknownScanner ouch2; // required
    public AccumuloSecurityException ouch3; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      OUCH1((short)1, "ouch1"),
      OUCH2((short)2, "ouch2"),
      OUCH3((short)3, "ouch3");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // OUCH1
            return OUCH1;
          case 2: // OUCH2
            return OUCH2;
          case 3: // OUCH3
            return OUCH3;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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.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.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);
    }

    public nextEntry_result() {
    }

    public nextEntry_result(
      KeyValueAndPeek success,
      NoMoreEntriesException ouch1,
      UnknownScanner ouch2,
      AccumuloSecurityException ouch3)
    {
      this();
      this.success = success;
      this.ouch1 = ouch1;
      this.ouch2 = ouch2;
      this.ouch3 = ouch3;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public nextEntry_result(nextEntry_result other) {
      if (other.isSetSuccess()) {
        this.success = new KeyValueAndPeek(other.success);
      }
      if (other.isSetOuch1()) {
        this.ouch1 = new NoMoreEntriesException(other.ouch1);
      }
      if (other.isSetOuch2()) {
        this.ouch2 = new UnknownScanner(other.ouch2);
      }
      if (other.isSetOuch3()) {
        this.ouch3 = new AccumuloSecurityException(other.ouch3);
      }
    }

    public nextEntry_result deepCopy() {
      return new nextEntry_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ouch1 = null;
      this.ouch2 = null;
      this.ouch3 = null;
    }

    public KeyValueAndPeek getSuccess() {
      return this.success;
    }

    public nextEntry_result setSuccess(KeyValueAndPeek success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return this.success != null;
    }

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public NoMoreEntriesException getOuch1() {
      return this.ouch1;
    }

    public nextEntry_result setOuch1(NoMoreEntriesException ouch1) {
      this.ouch1 = ouch1;
      return this;
    }

    public void unsetOuch1() {
      this.ouch1 = null;
    }

    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch1() {
      return this.ouch1 != null;
    }

    public void setOuch1IsSet(boolean value) {
      if (!value) {
        this.ouch1 = null;
      }
    }

    public UnknownScanner getOuch2() {
      return this.ouch2;
    }

    public nextEntry_result setOuch2(UnknownScanner ouch2) {
      this.ouch2 = ouch2;
      return this;
    }

    public void unsetOuch2() {
      this.ouch2 = null;
    }

    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch2() {
      return this.ouch2 != null;
    }

    public void setOuch2IsSet(boolean value) {
      if (!value) {
        this.ouch2 = null;
      }
    }

    public AccumuloSecurityException getOuch3() {
      return this.ouch3;
    }

    public nextEntry_result setOuch3(AccumuloSecurityException ouch3) {
      this.ouch3 = ouch3;
      return this;
    }

    public void unsetOuch3() {
      this.ouch3 = null;
    }

    /** Returns true if field ouch3 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch3() {
      return this.ouch3 != null;
    }

    public void setOuch3IsSet(boolean value) {
      if (!value) {
        this.ouch3 = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((KeyValueAndPeek)value);
        }
        break;

      case OUCH1:
        if (value == null) {
          unsetOuch1();
        } else {
          setOuch1((NoMoreEntriesException)value);
        }
        break;

      case OUCH2:
        if (value == null) {
          unsetOuch2();
        } else {
          setOuch2((UnknownScanner)value);
        }
        break;

      case OUCH3:
        if (value == null) {
          unsetOuch3();
        } else {
          setOuch3((AccumuloSecurityException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case OUCH1:
        return getOuch1();

      case OUCH2:
        return getOuch2();

      case OUCH3:
        return getOuch3();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case OUCH1:
        return isSetOuch1();
      case OUCH2:
        return isSetOuch2();
      case OUCH3:
        return isSetOuch3();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof nextEntry_result)
        return this.equals((nextEntry_result)that);
      return false;
    }

    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();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ouch1 = true && this.isSetOuch1();
      boolean that_present_ouch1 = true && that.isSetOuch1();
      if (this_present_ouch1 || that_present_ouch1) {
        if (!(this_present_ouch1 && that_present_ouch1))
          return false;
        if (!this.ouch1.equals(that.ouch1))
          return false;
      }

      boolean this_present_ouch2 = true && this.isSetOuch2();
      boolean that_present_ouch2 = true && that.isSetOuch2();
      if (this_present_ouch2 || that_present_ouch2) {
        if (!(this_present_ouch2 && that_present_ouch2))
          return false;
        if (!this.ouch2.equals(that.ouch2))
          return false;
      }

      boolean this_present_ouch3 = true && this.isSetOuch3();
      boolean that_present_ouch3 = true && that.isSetOuch3();
      if (this_present_ouch3 || that_present_ouch3) {
        if (!(this_present_ouch3 && that_present_ouch3))
          return false;
        if (!this.ouch3.equals(that.ouch3))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
      if (isSetSuccess())
        hashCode = hashCode * 8191 + success.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
      if (isSetOuch1())
        hashCode = hashCode * 8191 + ouch1.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
      if (isSetOuch2())
        hashCode = hashCode * 8191 + ouch2.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
      if (isSetOuch3())
        hashCode = hashCode * 8191 + ouch3.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(nextEntry_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch1()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch2()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch3()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch3, other.ouch3);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("nextEntry_result(");
      boolean first = true;

      sb.append("success:");
      if (this.success == null) {
        sb.append("null");
      } else {
        sb.append(this.success);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch1:");
      if (this.ouch1 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch1);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch2:");
      if (this.ouch2 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch2);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch3:");
      if (this.ouch3 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch3);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
      if (success != null) {
        success.validate();
      }
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class nextEntry_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public nextEntry_resultStandardScheme getScheme() {
        return new nextEntry_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.success = new KeyValueAndPeek();
                struct.success.read(iprot);
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // OUCH1
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch1 = new NoMoreEntriesException();
                struct.ouch1.read(iprot);
                struct.setOuch1IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OUCH2
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch2 = new UnknownScanner();
                struct.ouch2.read(iprot);
                struct.setOuch2IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // OUCH3
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch3 = new AccumuloSecurityException();
                struct.ouch3.read(iprot);
                struct.setOuch3IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, nextEntry_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          struct.success.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch1 != null) {
          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
          struct.ouch1.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch2 != null) {
          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
          struct.ouch2.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch3 != null) {
          oprot.writeFieldBegin(OUCH3_FIELD_DESC);
          struct.ouch3.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class nextEntry_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public nextEntry_resultTupleScheme getScheme() {
        return new nextEntry_resultTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetOuch1()) {
          optionals.set(1);
        }
        if (struct.isSetOuch2()) {
          optionals.set(2);
        }
        if (struct.isSetOuch3()) {
          optionals.set(3);
        }
        oprot.writeBitSet(optionals, 4);
        if (struct.isSetSuccess()) {
          struct.success.write(oprot);
        }
        if (struct.isSetOuch1()) {
          struct.ouch1.write(oprot);
        }
        if (struct.isSetOuch2()) {
          struct.ouch2.write(oprot);
        }
        if (struct.isSetOuch3()) {
          struct.ouch3.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, nextEntry_result struct) throws org.apache.thrift.TException {
        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);
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ouch1 = new NoMoreEntriesException();
          struct.ouch1.read(iprot);
          struct.setOuch1IsSet(true);
        }
        if (incoming.get(2)) {
          struct.ouch2 = new UnknownScanner();
          struct.ouch2.read(iprot);
          struct.setOuch2IsSet(true);
        }
        if (incoming.get(3)) {
          struct.ouch3 = new AccumuloSecurityException();
          struct.ouch3.read(iprot);
          struct.setOuch3IsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("nextK_args");

    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 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 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. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SCANNER((short)1, "scanner"),
      K((short)2, "k");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // SCANNER
            return SCANNER;
          case 2: // K
            return K;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __K_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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 = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(nextK_args.class, metaDataMap);
    }

    public nextK_args() {
    }

    public nextK_args(
      java.lang.String scanner,
      int k)
    {
      this();
      this.scanner = scanner;
      this.k = k;
      setKIsSet(true);
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public nextK_args(nextK_args other) {
      __isset_bitfield = other.__isset_bitfield;
      if (other.isSetScanner()) {
        this.scanner = other.scanner;
      }
      this.k = other.k;
    }

    public nextK_args deepCopy() {
      return new nextK_args(this);
    }

    @Override
    public void clear() {
      this.scanner = null;
      setKIsSet(false);
      this.k = 0;
    }

    public java.lang.String getScanner() {
      return this.scanner;
    }

    public nextK_args setScanner(java.lang.String scanner) {
      this.scanner = scanner;
      return this;
    }

    public void unsetScanner() {
      this.scanner = null;
    }

    /** Returns true if field scanner is set (has been assigned a value) and false otherwise */
    public boolean isSetScanner() {
      return this.scanner != null;
    }

    public void setScannerIsSet(boolean value) {
      if (!value) {
        this.scanner = null;
      }
    }

    public int getK() {
      return this.k;
    }

    public nextK_args setK(int k) {
      this.k = k;
      setKIsSet(true);
      return this;
    }

    public void unsetK() {
      __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 org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __K_ISSET_ID);
    }

    public void setKIsSet(boolean value) {
      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __K_ISSET_ID, value);
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SCANNER:
        if (value == null) {
          unsetScanner();
        } else {
          setScanner((java.lang.String)value);
        }
        break;

      case K:
        if (value == null) {
          unsetK();
        } else {
          setK((java.lang.Integer)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SCANNER:
        return getScanner();

      case K:
        return getK();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SCANNER:
        return isSetScanner();
      case K:
        return isSetK();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof nextK_args)
        return this.equals((nextK_args)that);
      return false;
    }

    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();
      if (this_present_scanner || that_present_scanner) {
        if (!(this_present_scanner && that_present_scanner))
          return false;
        if (!this.scanner.equals(that.scanner))
          return false;
      }

      boolean this_present_k = true;
      boolean that_present_k = true;
      if (this_present_k || that_present_k) {
        if (!(this_present_k && that_present_k))
          return false;
        if (this.k != that.k)
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetScanner()) ? 131071 : 524287);
      if (isSetScanner())
        hashCode = hashCode * 8191 + scanner.hashCode();

      hashCode = hashCode * 8191 + k;

      return hashCode;
    }

    @Override
    public int compareTo(nextK_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetScanner()).compareTo(other.isSetScanner());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetScanner()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.scanner, other.scanner);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetK()).compareTo(other.isSetK());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetK()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.k, other.k);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("nextK_args(");
      boolean first = true;

      sb.append("scanner:");
      if (this.scanner == null) {
        sb.append("null");
      } else {
        sb.append(this.scanner);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("k:");
      sb.append(this.k);
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, 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;
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class nextK_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public nextK_argsStandardScheme getScheme() {
        return new nextK_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // SCANNER
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.scanner = iprot.readString();
                struct.setScannerIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // K
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.k = iprot.readI32();
                struct.setKIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, nextK_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.scanner != null) {
          oprot.writeFieldBegin(SCANNER_FIELD_DESC);
          oprot.writeString(struct.scanner);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldBegin(K_FIELD_DESC);
        oprot.writeI32(struct.k);
        oprot.writeFieldEnd();
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    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 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 {
        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);
        }
        if (struct.isSetK()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetScanner()) {
          oprot.writeString(struct.scanner);
        }
        if (struct.isSetK()) {
          oprot.writeI32(struct.k);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, nextK_args struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.k = iprot.readI32();
          struct.setKIsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("nextK_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.STRUCT, (short)0);
    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField OUCH3_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch3", org.apache.thrift.protocol.TType.STRUCT, (short)3);

    private static final 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
    public UnknownScanner ouch2; // required
    public AccumuloSecurityException ouch3; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      OUCH1((short)1, "ouch1"),
      OUCH2((short)2, "ouch2"),
      OUCH3((short)3, "ouch3");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // OUCH1
            return OUCH1;
          case 2: // OUCH2
            return OUCH2;
          case 3: // OUCH3
            return OUCH3;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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.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.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);
    }

    public nextK_result() {
    }

    public nextK_result(
      ScanResult success,
      NoMoreEntriesException ouch1,
      UnknownScanner ouch2,
      AccumuloSecurityException ouch3)
    {
      this();
      this.success = success;
      this.ouch1 = ouch1;
      this.ouch2 = ouch2;
      this.ouch3 = ouch3;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public nextK_result(nextK_result other) {
      if (other.isSetSuccess()) {
        this.success = new ScanResult(other.success);
      }
      if (other.isSetOuch1()) {
        this.ouch1 = new NoMoreEntriesException(other.ouch1);
      }
      if (other.isSetOuch2()) {
        this.ouch2 = new UnknownScanner(other.ouch2);
      }
      if (other.isSetOuch3()) {
        this.ouch3 = new AccumuloSecurityException(other.ouch3);
      }
    }

    public nextK_result deepCopy() {
      return new nextK_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ouch1 = null;
      this.ouch2 = null;
      this.ouch3 = null;
    }

    public ScanResult getSuccess() {
      return this.success;
    }

    public nextK_result setSuccess(ScanResult success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return this.success != null;
    }

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public NoMoreEntriesException getOuch1() {
      return this.ouch1;
    }

    public nextK_result setOuch1(NoMoreEntriesException ouch1) {
      this.ouch1 = ouch1;
      return this;
    }

    public void unsetOuch1() {
      this.ouch1 = null;
    }

    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch1() {
      return this.ouch1 != null;
    }

    public void setOuch1IsSet(boolean value) {
      if (!value) {
        this.ouch1 = null;
      }
    }

    public UnknownScanner getOuch2() {
      return this.ouch2;
    }

    public nextK_result setOuch2(UnknownScanner ouch2) {
      this.ouch2 = ouch2;
      return this;
    }

    public void unsetOuch2() {
      this.ouch2 = null;
    }

    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch2() {
      return this.ouch2 != null;
    }

    public void setOuch2IsSet(boolean value) {
      if (!value) {
        this.ouch2 = null;
      }
    }

    public AccumuloSecurityException getOuch3() {
      return this.ouch3;
    }

    public nextK_result setOuch3(AccumuloSecurityException ouch3) {
      this.ouch3 = ouch3;
      return this;
    }

    public void unsetOuch3() {
      this.ouch3 = null;
    }

    /** Returns true if field ouch3 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch3() {
      return this.ouch3 != null;
    }

    public void setOuch3IsSet(boolean value) {
      if (!value) {
        this.ouch3 = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((ScanResult)value);
        }
        break;

      case OUCH1:
        if (value == null) {
          unsetOuch1();
        } else {
          setOuch1((NoMoreEntriesException)value);
        }
        break;

      case OUCH2:
        if (value == null) {
          unsetOuch2();
        } else {
          setOuch2((UnknownScanner)value);
        }
        break;

      case OUCH3:
        if (value == null) {
          unsetOuch3();
        } else {
          setOuch3((AccumuloSecurityException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case OUCH1:
        return getOuch1();

      case OUCH2:
        return getOuch2();

      case OUCH3:
        return getOuch3();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case OUCH1:
        return isSetOuch1();
      case OUCH2:
        return isSetOuch2();
      case OUCH3:
        return isSetOuch3();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof nextK_result)
        return this.equals((nextK_result)that);
      return false;
    }

    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();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ouch1 = true && this.isSetOuch1();
      boolean that_present_ouch1 = true && that.isSetOuch1();
      if (this_present_ouch1 || that_present_ouch1) {
        if (!(this_present_ouch1 && that_present_ouch1))
          return false;
        if (!this.ouch1.equals(that.ouch1))
          return false;
      }

      boolean this_present_ouch2 = true && this.isSetOuch2();
      boolean that_present_ouch2 = true && that.isSetOuch2();
      if (this_present_ouch2 || that_present_ouch2) {
        if (!(this_present_ouch2 && that_present_ouch2))
          return false;
        if (!this.ouch2.equals(that.ouch2))
          return false;
      }

      boolean this_present_ouch3 = true && this.isSetOuch3();
      boolean that_present_ouch3 = true && that.isSetOuch3();
      if (this_present_ouch3 || that_present_ouch3) {
        if (!(this_present_ouch3 && that_present_ouch3))
          return false;
        if (!this.ouch3.equals(that.ouch3))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
      if (isSetSuccess())
        hashCode = hashCode * 8191 + success.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
      if (isSetOuch1())
        hashCode = hashCode * 8191 + ouch1.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
      if (isSetOuch2())
        hashCode = hashCode * 8191 + ouch2.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
      if (isSetOuch3())
        hashCode = hashCode * 8191 + ouch3.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(nextK_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch1()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch2()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch3()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch3, other.ouch3);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("nextK_result(");
      boolean first = true;

      sb.append("success:");
      if (this.success == null) {
        sb.append("null");
      } else {
        sb.append(this.success);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch1:");
      if (this.ouch1 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch1);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch2:");
      if (this.ouch2 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch2);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch3:");
      if (this.ouch3 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch3);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
      if (success != null) {
        success.validate();
      }
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class nextK_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public nextK_resultStandardScheme getScheme() {
        return new nextK_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.success = new ScanResult();
                struct.success.read(iprot);
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // OUCH1
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch1 = new NoMoreEntriesException();
                struct.ouch1.read(iprot);
                struct.setOuch1IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OUCH2
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch2 = new UnknownScanner();
                struct.ouch2.read(iprot);
                struct.setOuch2IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // OUCH3
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch3 = new AccumuloSecurityException();
                struct.ouch3.read(iprot);
                struct.setOuch3IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, nextK_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          struct.success.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch1 != null) {
          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
          struct.ouch1.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch2 != null) {
          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
          struct.ouch2.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch3 != null) {
          oprot.writeFieldBegin(OUCH3_FIELD_DESC);
          struct.ouch3.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class nextK_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public nextK_resultTupleScheme getScheme() {
        return new nextK_resultTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetOuch1()) {
          optionals.set(1);
        }
        if (struct.isSetOuch2()) {
          optionals.set(2);
        }
        if (struct.isSetOuch3()) {
          optionals.set(3);
        }
        oprot.writeBitSet(optionals, 4);
        if (struct.isSetSuccess()) {
          struct.success.write(oprot);
        }
        if (struct.isSetOuch1()) {
          struct.ouch1.write(oprot);
        }
        if (struct.isSetOuch2()) {
          struct.ouch2.write(oprot);
        }
        if (struct.isSetOuch3()) {
          struct.ouch3.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, nextK_result struct) throws org.apache.thrift.TException {
        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);
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ouch1 = new NoMoreEntriesException();
          struct.ouch1.read(iprot);
          struct.setOuch1IsSet(true);
        }
        if (incoming.get(2)) {
          struct.ouch2 = new UnknownScanner();
          struct.ouch2.read(iprot);
          struct.setOuch2IsSet(true);
        }
        if (incoming.get(3)) {
          struct.ouch3 = new AccumuloSecurityException();
          struct.ouch3.read(iprot);
          struct.setOuch3IsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("closeScanner_args");

    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.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new closeScanner_argsStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new closeScanner_argsTupleSchemeFactory();

    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 java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // SCANNER
            return SCANNER;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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 = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(closeScanner_args.class, metaDataMap);
    }

    public closeScanner_args() {
    }

    public closeScanner_args(
      java.lang.String scanner)
    {
      this();
      this.scanner = scanner;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public closeScanner_args(closeScanner_args other) {
      if (other.isSetScanner()) {
        this.scanner = other.scanner;
      }
    }

    public closeScanner_args deepCopy() {
      return new closeScanner_args(this);
    }

    @Override
    public void clear() {
      this.scanner = null;
    }

    public java.lang.String getScanner() {
      return this.scanner;
    }

    public closeScanner_args setScanner(java.lang.String scanner) {
      this.scanner = scanner;
      return this;
    }

    public void unsetScanner() {
      this.scanner = null;
    }

    /** Returns true if field scanner is set (has been assigned a value) and false otherwise */
    public boolean isSetScanner() {
      return this.scanner != null;
    }

    public void setScannerIsSet(boolean value) {
      if (!value) {
        this.scanner = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SCANNER:
        if (value == null) {
          unsetScanner();
        } else {
          setScanner((java.lang.String)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SCANNER:
        return getScanner();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SCANNER:
        return isSetScanner();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof closeScanner_args)
        return this.equals((closeScanner_args)that);
      return false;
    }

    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();
      if (this_present_scanner || that_present_scanner) {
        if (!(this_present_scanner && that_present_scanner))
          return false;
        if (!this.scanner.equals(that.scanner))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetScanner()) ? 131071 : 524287);
      if (isSetScanner())
        hashCode = hashCode * 8191 + scanner.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(closeScanner_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetScanner()).compareTo(other.isSetScanner());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetScanner()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.scanner, other.scanner);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("closeScanner_args(");
      boolean first = true;

      sb.append("scanner:");
      if (this.scanner == null) {
        sb.append("null");
      } else {
        sb.append(this.scanner);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class closeScanner_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public closeScanner_argsStandardScheme getScheme() {
        return new closeScanner_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // SCANNER
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.scanner = iprot.readString();
                struct.setScannerIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, closeScanner_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.scanner != null) {
          oprot.writeFieldBegin(SCANNER_FIELD_DESC);
          oprot.writeString(struct.scanner);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    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 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 {
        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);
        }
        oprot.writeBitSet(optionals, 1);
        if (struct.isSetScanner()) {
          oprot.writeString(struct.scanner);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, closeScanner_args struct) throws org.apache.thrift.TException {
        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);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("closeScanner_result");

    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);

    private static final org.apache.thrift.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

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      OUCH1((short)1, "ouch1");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // OUCH1
            return OUCH1;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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);
    }

    public closeScanner_result() {
    }

    public closeScanner_result(
      UnknownScanner ouch1)
    {
      this();
      this.ouch1 = ouch1;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public closeScanner_result(closeScanner_result other) {
      if (other.isSetOuch1()) {
        this.ouch1 = new UnknownScanner(other.ouch1);
      }
    }

    public closeScanner_result deepCopy() {
      return new closeScanner_result(this);
    }

    @Override
    public void clear() {
      this.ouch1 = null;
    }

    public UnknownScanner getOuch1() {
      return this.ouch1;
    }

    public closeScanner_result setOuch1(UnknownScanner ouch1) {
      this.ouch1 = ouch1;
      return this;
    }

    public void unsetOuch1() {
      this.ouch1 = null;
    }

    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch1() {
      return this.ouch1 != null;
    }

    public void setOuch1IsSet(boolean value) {
      if (!value) {
        this.ouch1 = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case OUCH1:
        if (value == null) {
          unsetOuch1();
        } else {
          setOuch1((UnknownScanner)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case OUCH1:
        return getOuch1();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case OUCH1:
        return isSetOuch1();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof closeScanner_result)
        return this.equals((closeScanner_result)that);
      return false;
    }

    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();
      if (this_present_ouch1 || that_present_ouch1) {
        if (!(this_present_ouch1 && that_present_ouch1))
          return false;
        if (!this.ouch1.equals(that.ouch1))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
      if (isSetOuch1())
        hashCode = hashCode * 8191 + ouch1.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(closeScanner_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch1()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("closeScanner_result(");
      boolean first = true;

      sb.append("ouch1:");
      if (this.ouch1 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch1);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class closeScanner_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public closeScanner_resultStandardScheme getScheme() {
        return new closeScanner_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // OUCH1
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch1 = new UnknownScanner();
                struct.ouch1.read(iprot);
                struct.setOuch1IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, closeScanner_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.ouch1 != null) {
          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
          struct.ouch1.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    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 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 {
        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);
        }
        oprot.writeBitSet(optionals, 1);
        if (struct.isSetOuch1()) {
          struct.ouch1.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, closeScanner_result struct) throws org.apache.thrift.TException {
        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);
          struct.setOuch1IsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("updateAndFlush_args");

    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField 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 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 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 {
      LOGIN((short)1, "login"),
      TABLE_NAME((short)2, "tableName"),
      CELLS((short)3, "cells");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // LOGIN
            return LOGIN;
          case 2: // TABLE_NAME
            return TABLE_NAME;
          case 3: // CELLS
            return CELLS;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.CELLS, new org.apache.thrift.meta_data.FieldMetaData("cells", 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.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
                  new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, ColumnUpdate.class)))));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(updateAndFlush_args.class, metaDataMap);
    }

    public updateAndFlush_args() {
    }

    public updateAndFlush_args(
      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);
      this.tableName = tableName;
      this.cells = cells;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public updateAndFlush_args(updateAndFlush_args other) {
      if (other.isSetLogin()) {
        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
      }
      if (other.isSetTableName()) {
        this.tableName = other.tableName;
      }
      if (other.isSetCells()) {
        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()) {

          java.nio.ByteBuffer other_element_key = other_element.getKey();
          java.util.List<ColumnUpdate> other_element_value = other_element.getValue();

          java.nio.ByteBuffer __this__cells_copy_key = org.apache.thrift.TBaseHelper.copyBinary(other_element_key);

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

          __this__cells.put(__this__cells_copy_key, __this__cells_copy_value);
        }
        this.cells = __this__cells;
      }
    }

    public updateAndFlush_args deepCopy() {
      return new updateAndFlush_args(this);
    }

    @Override
    public void clear() {
      this.login = null;
      this.tableName = null;
      this.cells = null;
    }

    public byte[] getLogin() {
      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
      return login == null ? null : login.array();
    }

    public java.nio.ByteBuffer bufferForLogin() {
      return org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    public updateAndFlush_args setLogin(byte[] login) {
      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
      return this;
    }

    public updateAndFlush_args setLogin(java.nio.ByteBuffer login) {
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      return this;
    }

    public void unsetLogin() {
      this.login = null;
    }

    /** Returns true if field login is set (has been assigned a value) and false otherwise */
    public boolean isSetLogin() {
      return this.login != null;
    }

    public void setLoginIsSet(boolean value) {
      if (!value) {
        this.login = null;
      }
    }

    public java.lang.String getTableName() {
      return this.tableName;
    }

    public updateAndFlush_args setTableName(java.lang.String tableName) {
      this.tableName = tableName;
      return this;
    }

    public void unsetTableName() {
      this.tableName = null;
    }

    /** Returns true if field tableName is set (has been assigned a value) and false otherwise */
    public boolean isSetTableName() {
      return this.tableName != null;
    }

    public void setTableNameIsSet(boolean value) {
      if (!value) {
        this.tableName = null;
      }
    }

    public int getCellsSize() {
      return (this.cells == null) ? 0 : this.cells.size();
    }

    public void putToCells(java.nio.ByteBuffer key, java.util.List<ColumnUpdate> val) {
      if (this.cells == null) {
        this.cells = new java.util.HashMap<java.nio.ByteBuffer,java.util.List<ColumnUpdate>>();
      }
      this.cells.put(key, val);
    }

    public java.util.Map<java.nio.ByteBuffer,java.util.List<ColumnUpdate>> getCells() {
      return this.cells;
    }

    public updateAndFlush_args setCells(java.util.Map<java.nio.ByteBuffer,java.util.List<ColumnUpdate>> cells) {
      this.cells = cells;
      return this;
    }

    public void unsetCells() {
      this.cells = null;
    }

    /** Returns true if field cells is set (has been assigned a value) and false otherwise */
    public boolean isSetCells() {
      return this.cells != null;
    }

    public void setCellsIsSet(boolean value) {
      if (!value) {
        this.cells = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case LOGIN:
        if (value == null) {
          unsetLogin();
        } else {
          if (value instanceof byte[]) {
            setLogin((byte[])value);
          } else {
            setLogin((java.nio.ByteBuffer)value);
          }
        }
        break;

      case TABLE_NAME:
        if (value == null) {
          unsetTableName();
        } else {
          setTableName((java.lang.String)value);
        }
        break;

      case CELLS:
        if (value == null) {
          unsetCells();
        } else {
          setCells((java.util.Map<java.nio.ByteBuffer,java.util.List<ColumnUpdate>>)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case LOGIN:
        return getLogin();

      case TABLE_NAME:
        return getTableName();

      case CELLS:
        return getCells();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case LOGIN:
        return isSetLogin();
      case TABLE_NAME:
        return isSetTableName();
      case CELLS:
        return isSetCells();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof updateAndFlush_args)
        return this.equals((updateAndFlush_args)that);
      return false;
    }

    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();
      if (this_present_login || that_present_login) {
        if (!(this_present_login && that_present_login))
          return false;
        if (!this.login.equals(that.login))
          return false;
      }

      boolean this_present_tableName = true && this.isSetTableName();
      boolean that_present_tableName = true && that.isSetTableName();
      if (this_present_tableName || that_present_tableName) {
        if (!(this_present_tableName && that_present_tableName))
          return false;
        if (!this.tableName.equals(that.tableName))
          return false;
      }

      boolean this_present_cells = true && this.isSetCells();
      boolean that_present_cells = true && that.isSetCells();
      if (this_present_cells || that_present_cells) {
        if (!(this_present_cells && that_present_cells))
          return false;
        if (!this.cells.equals(that.cells))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
      if (isSetLogin())
        hashCode = hashCode * 8191 + login.hashCode();

      hashCode = hashCode * 8191 + ((isSetTableName()) ? 131071 : 524287);
      if (isSetTableName())
        hashCode = hashCode * 8191 + tableName.hashCode();

      hashCode = hashCode * 8191 + ((isSetCells()) ? 131071 : 524287);
      if (isSetCells())
        hashCode = hashCode * 8191 + cells.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(updateAndFlush_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLogin()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetTableName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.tableName, other.tableName);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetCells()).compareTo(other.isSetCells());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetCells()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.cells, other.cells);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("updateAndFlush_args(");
      boolean first = true;

      sb.append("login:");
      if (this.login == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.login, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("tableName:");
      if (this.tableName == null) {
        sb.append("null");
      } else {
        sb.append(this.tableName);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("cells:");
      if (this.cells == null) {
        sb.append("null");
      } else {
        sb.append(this.cells);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class updateAndFlush_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public updateAndFlush_argsStandardScheme getScheme() {
        return new updateAndFlush_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // LOGIN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.login = iprot.readBinary();
                struct.setLoginIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // TABLE_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.tableName = iprot.readString();
                struct.setTableNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // CELLS
              if (schemeField.type == org.apache.thrift.protocol.TType.MAP) {
                {
                  org.apache.thrift.protocol.TMap _map442 = iprot.readMapBegin();
                  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 java.util.ArrayList<ColumnUpdate>(_list446.size);
                      ColumnUpdate _elem447;
                      for (int _i448 = 0; _i448 < _list446.size; ++_i448)
                      {
                        _elem447 = new ColumnUpdate();
                        _elem447.read(iprot);
                        _val444.add(_elem447);
                      }
                      iprot.readListEnd();
                    }
                    struct.cells.put(_key443, _val444);
                  }
                  iprot.readMapEnd();
                }
                struct.setCellsIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, updateAndFlush_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.login != null) {
          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
          oprot.writeBinary(struct.login);
          oprot.writeFieldEnd();
        }
        if (struct.tableName != null) {
          oprot.writeFieldBegin(TABLE_NAME_FIELD_DESC);
          oprot.writeString(struct.tableName);
          oprot.writeFieldEnd();
        }
        if (struct.cells != null) {
          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 (java.util.Map.Entry<java.nio.ByteBuffer, java.util.List<ColumnUpdate>> _iter449 : struct.cells.entrySet())
            {
              oprot.writeBinary(_iter449.getKey());
              {
                oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, _iter449.getValue().size()));
                for (ColumnUpdate _iter450 : _iter449.getValue())
                {
                  _iter450.write(oprot);
                }
                oprot.writeListEnd();
              }
            }
            oprot.writeMapEnd();
          }
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    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 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 {
        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);
        }
        if (struct.isSetTableName()) {
          optionals.set(1);
        }
        if (struct.isSetCells()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetLogin()) {
          oprot.writeBinary(struct.login);
        }
        if (struct.isSetTableName()) {
          oprot.writeString(struct.tableName);
        }
        if (struct.isSetCells()) {
          {
            oprot.writeI32(struct.cells.size());
            for (java.util.Map.Entry<java.nio.ByteBuffer, java.util.List<ColumnUpdate>> _iter451 : struct.cells.entrySet())
            {
              oprot.writeBinary(_iter451.getKey());
              {
                oprot.writeI32(_iter451.getValue().size());
                for (ColumnUpdate _iter452 : _iter451.getValue())
                {
                  _iter452.write(oprot);
                }
              }
            }
          }
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, updateAndFlush_args struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.tableName = iprot.readString();
          struct.setTableNameIsSet(true);
        }
        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 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 java.util.ArrayList<ColumnUpdate>(_list457.size);
                ColumnUpdate _elem458;
                for (int _i459 = 0; _i459 < _list457.size; ++_i459)
                {
                  _elem458 = new ColumnUpdate();
                  _elem458.read(iprot);
                  _val455.add(_elem458);
                }
              }
              struct.cells.put(_key454, _val455);
            }
          }
          struct.setCellsIsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("updateAndFlush_result");

    private static final org.apache.thrift.protocol.TField OUTCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("outch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField OUCH3_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch3", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    private static final org.apache.thrift.protocol.TField OUCH4_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch4", org.apache.thrift.protocol.TType.STRUCT, (short)4);

    private static final 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
    public TableNotFoundException ouch3; // required
    public MutationsRejectedException ouch4; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      OUTCH1((short)1, "outch1"),
      OUCH2((short)2, "ouch2"),
      OUCH3((short)3, "ouch3"),
      OUCH4((short)4, "ouch4");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // OUTCH1
            return OUTCH1;
          case 2: // OUCH2
            return OUCH2;
          case 3: // OUCH3
            return OUCH3;
          case 4: // OUCH4
            return OUCH4;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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.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.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.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);
    }

    public updateAndFlush_result() {
    }

    public updateAndFlush_result(
      AccumuloException outch1,
      AccumuloSecurityException ouch2,
      TableNotFoundException ouch3,
      MutationsRejectedException ouch4)
    {
      this();
      this.outch1 = outch1;
      this.ouch2 = ouch2;
      this.ouch3 = ouch3;
      this.ouch4 = ouch4;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public updateAndFlush_result(updateAndFlush_result other) {
      if (other.isSetOutch1()) {
        this.outch1 = new AccumuloException(other.outch1);
      }
      if (other.isSetOuch2()) {
        this.ouch2 = new AccumuloSecurityException(other.ouch2);
      }
      if (other.isSetOuch3()) {
        this.ouch3 = new TableNotFoundException(other.ouch3);
      }
      if (other.isSetOuch4()) {
        this.ouch4 = new MutationsRejectedException(other.ouch4);
      }
    }

    public updateAndFlush_result deepCopy() {
      return new updateAndFlush_result(this);
    }

    @Override
    public void clear() {
      this.outch1 = null;
      this.ouch2 = null;
      this.ouch3 = null;
      this.ouch4 = null;
    }

    public AccumuloException getOutch1() {
      return this.outch1;
    }

    public updateAndFlush_result setOutch1(AccumuloException outch1) {
      this.outch1 = outch1;
      return this;
    }

    public void unsetOutch1() {
      this.outch1 = null;
    }

    /** Returns true if field outch1 is set (has been assigned a value) and false otherwise */
    public boolean isSetOutch1() {
      return this.outch1 != null;
    }

    public void setOutch1IsSet(boolean value) {
      if (!value) {
        this.outch1 = null;
      }
    }

    public AccumuloSecurityException getOuch2() {
      return this.ouch2;
    }

    public updateAndFlush_result setOuch2(AccumuloSecurityException ouch2) {
      this.ouch2 = ouch2;
      return this;
    }

    public void unsetOuch2() {
      this.ouch2 = null;
    }

    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch2() {
      return this.ouch2 != null;
    }

    public void setOuch2IsSet(boolean value) {
      if (!value) {
        this.ouch2 = null;
      }
    }

    public TableNotFoundException getOuch3() {
      return this.ouch3;
    }

    public updateAndFlush_result setOuch3(TableNotFoundException ouch3) {
      this.ouch3 = ouch3;
      return this;
    }

    public void unsetOuch3() {
      this.ouch3 = null;
    }

    /** Returns true if field ouch3 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch3() {
      return this.ouch3 != null;
    }

    public void setOuch3IsSet(boolean value) {
      if (!value) {
        this.ouch3 = null;
      }
    }

    public MutationsRejectedException getOuch4() {
      return this.ouch4;
    }

    public updateAndFlush_result setOuch4(MutationsRejectedException ouch4) {
      this.ouch4 = ouch4;
      return this;
    }

    public void unsetOuch4() {
      this.ouch4 = null;
    }

    /** Returns true if field ouch4 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch4() {
      return this.ouch4 != null;
    }

    public void setOuch4IsSet(boolean value) {
      if (!value) {
        this.ouch4 = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case OUTCH1:
        if (value == null) {
          unsetOutch1();
        } else {
          setOutch1((AccumuloException)value);
        }
        break;

      case OUCH2:
        if (value == null) {
          unsetOuch2();
        } else {
          setOuch2((AccumuloSecurityException)value);
        }
        break;

      case OUCH3:
        if (value == null) {
          unsetOuch3();
        } else {
          setOuch3((TableNotFoundException)value);
        }
        break;

      case OUCH4:
        if (value == null) {
          unsetOuch4();
        } else {
          setOuch4((MutationsRejectedException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case OUTCH1:
        return getOutch1();

      case OUCH2:
        return getOuch2();

      case OUCH3:
        return getOuch3();

      case OUCH4:
        return getOuch4();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case OUTCH1:
        return isSetOutch1();
      case OUCH2:
        return isSetOuch2();
      case OUCH3:
        return isSetOuch3();
      case OUCH4:
        return isSetOuch4();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof updateAndFlush_result)
        return this.equals((updateAndFlush_result)that);
      return false;
    }

    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();
      if (this_present_outch1 || that_present_outch1) {
        if (!(this_present_outch1 && that_present_outch1))
          return false;
        if (!this.outch1.equals(that.outch1))
          return false;
      }

      boolean this_present_ouch2 = true && this.isSetOuch2();
      boolean that_present_ouch2 = true && that.isSetOuch2();
      if (this_present_ouch2 || that_present_ouch2) {
        if (!(this_present_ouch2 && that_present_ouch2))
          return false;
        if (!this.ouch2.equals(that.ouch2))
          return false;
      }

      boolean this_present_ouch3 = true && this.isSetOuch3();
      boolean that_present_ouch3 = true && that.isSetOuch3();
      if (this_present_ouch3 || that_present_ouch3) {
        if (!(this_present_ouch3 && that_present_ouch3))
          return false;
        if (!this.ouch3.equals(that.ouch3))
          return false;
      }

      boolean this_present_ouch4 = true && this.isSetOuch4();
      boolean that_present_ouch4 = true && that.isSetOuch4();
      if (this_present_ouch4 || that_present_ouch4) {
        if (!(this_present_ouch4 && that_present_ouch4))
          return false;
        if (!this.ouch4.equals(that.ouch4))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetOutch1()) ? 131071 : 524287);
      if (isSetOutch1())
        hashCode = hashCode * 8191 + outch1.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
      if (isSetOuch2())
        hashCode = hashCode * 8191 + ouch2.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
      if (isSetOuch3())
        hashCode = hashCode * 8191 + ouch3.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch4()) ? 131071 : 524287);
      if (isSetOuch4())
        hashCode = hashCode * 8191 + ouch4.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(updateAndFlush_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetOutch1()).compareTo(other.isSetOutch1());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOutch1()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.outch1, other.outch1);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch2()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch3()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch3, other.ouch3);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch4()).compareTo(other.isSetOuch4());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch4()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch4, other.ouch4);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("updateAndFlush_result(");
      boolean first = true;

      sb.append("outch1:");
      if (this.outch1 == null) {
        sb.append("null");
      } else {
        sb.append(this.outch1);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch2:");
      if (this.ouch2 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch2);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch3:");
      if (this.ouch3 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch3);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch4:");
      if (this.ouch4 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch4);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class updateAndFlush_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public updateAndFlush_resultStandardScheme getScheme() {
        return new updateAndFlush_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // OUTCH1
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.outch1 = new AccumuloException();
                struct.outch1.read(iprot);
                struct.setOutch1IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OUCH2
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch2 = new AccumuloSecurityException();
                struct.ouch2.read(iprot);
                struct.setOuch2IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // OUCH3
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch3 = new TableNotFoundException();
                struct.ouch3.read(iprot);
                struct.setOuch3IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // OUCH4
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch4 = new MutationsRejectedException();
                struct.ouch4.read(iprot);
                struct.setOuch4IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, updateAndFlush_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.outch1 != null) {
          oprot.writeFieldBegin(OUTCH1_FIELD_DESC);
          struct.outch1.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch2 != null) {
          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
          struct.ouch2.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch3 != null) {
          oprot.writeFieldBegin(OUCH3_FIELD_DESC);
          struct.ouch3.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch4 != null) {
          oprot.writeFieldBegin(OUCH4_FIELD_DESC);
          struct.ouch4.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class updateAndFlush_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public updateAndFlush_resultTupleScheme getScheme() {
        return new updateAndFlush_resultTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetOuch2()) {
          optionals.set(1);
        }
        if (struct.isSetOuch3()) {
          optionals.set(2);
        }
        if (struct.isSetOuch4()) {
          optionals.set(3);
        }
        oprot.writeBitSet(optionals, 4);
        if (struct.isSetOutch1()) {
          struct.outch1.write(oprot);
        }
        if (struct.isSetOuch2()) {
          struct.ouch2.write(oprot);
        }
        if (struct.isSetOuch3()) {
          struct.ouch3.write(oprot);
        }
        if (struct.isSetOuch4()) {
          struct.ouch4.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, updateAndFlush_result struct) throws org.apache.thrift.TException {
        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);
          struct.setOutch1IsSet(true);
        }
        if (incoming.get(1)) {
          struct.ouch2 = new AccumuloSecurityException();
          struct.ouch2.read(iprot);
          struct.setOuch2IsSet(true);
        }
        if (incoming.get(2)) {
          struct.ouch3 = new TableNotFoundException();
          struct.ouch3.read(iprot);
          struct.setOuch3IsSet(true);
        }
        if (incoming.get(3)) {
          struct.ouch4 = new MutationsRejectedException();
          struct.ouch4.read(iprot);
          struct.setOuch4IsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("createWriter_args");

    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField 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 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 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. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      LOGIN((short)1, "login"),
      TABLE_NAME((short)2, "tableName"),
      OPTS((short)3, "opts");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // LOGIN
            return LOGIN;
          case 2: // TABLE_NAME
            return TABLE_NAME;
          case 3: // OPTS
            return OPTS;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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 = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(createWriter_args.class, metaDataMap);
    }

    public createWriter_args() {
    }

    public createWriter_args(
      java.nio.ByteBuffer login,
      java.lang.String tableName,
      WriterOptions opts)
    {
      this();
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      this.tableName = tableName;
      this.opts = opts;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public createWriter_args(createWriter_args other) {
      if (other.isSetLogin()) {
        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
      }
      if (other.isSetTableName()) {
        this.tableName = other.tableName;
      }
      if (other.isSetOpts()) {
        this.opts = new WriterOptions(other.opts);
      }
    }

    public createWriter_args deepCopy() {
      return new createWriter_args(this);
    }

    @Override
    public void clear() {
      this.login = null;
      this.tableName = null;
      this.opts = null;
    }

    public byte[] getLogin() {
      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
      return login == null ? null : login.array();
    }

    public java.nio.ByteBuffer bufferForLogin() {
      return org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    public createWriter_args setLogin(byte[] login) {
      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
      return this;
    }

    public createWriter_args setLogin(java.nio.ByteBuffer login) {
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      return this;
    }

    public void unsetLogin() {
      this.login = null;
    }

    /** Returns true if field login is set (has been assigned a value) and false otherwise */
    public boolean isSetLogin() {
      return this.login != null;
    }

    public void setLoginIsSet(boolean value) {
      if (!value) {
        this.login = null;
      }
    }

    public java.lang.String getTableName() {
      return this.tableName;
    }

    public createWriter_args setTableName(java.lang.String tableName) {
      this.tableName = tableName;
      return this;
    }

    public void unsetTableName() {
      this.tableName = null;
    }

    /** Returns true if field tableName is set (has been assigned a value) and false otherwise */
    public boolean isSetTableName() {
      return this.tableName != null;
    }

    public void setTableNameIsSet(boolean value) {
      if (!value) {
        this.tableName = null;
      }
    }

    public WriterOptions getOpts() {
      return this.opts;
    }

    public createWriter_args setOpts(WriterOptions opts) {
      this.opts = opts;
      return this;
    }

    public void unsetOpts() {
      this.opts = null;
    }

    /** Returns true if field opts is set (has been assigned a value) and false otherwise */
    public boolean isSetOpts() {
      return this.opts != null;
    }

    public void setOptsIsSet(boolean value) {
      if (!value) {
        this.opts = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case LOGIN:
        if (value == null) {
          unsetLogin();
        } else {
          if (value instanceof byte[]) {
            setLogin((byte[])value);
          } else {
            setLogin((java.nio.ByteBuffer)value);
          }
        }
        break;

      case TABLE_NAME:
        if (value == null) {
          unsetTableName();
        } else {
          setTableName((java.lang.String)value);
        }
        break;

      case OPTS:
        if (value == null) {
          unsetOpts();
        } else {
          setOpts((WriterOptions)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case LOGIN:
        return getLogin();

      case TABLE_NAME:
        return getTableName();

      case OPTS:
        return getOpts();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case LOGIN:
        return isSetLogin();
      case TABLE_NAME:
        return isSetTableName();
      case OPTS:
        return isSetOpts();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof createWriter_args)
        return this.equals((createWriter_args)that);
      return false;
    }

    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();
      if (this_present_login || that_present_login) {
        if (!(this_present_login && that_present_login))
          return false;
        if (!this.login.equals(that.login))
          return false;
      }

      boolean this_present_tableName = true && this.isSetTableName();
      boolean that_present_tableName = true && that.isSetTableName();
      if (this_present_tableName || that_present_tableName) {
        if (!(this_present_tableName && that_present_tableName))
          return false;
        if (!this.tableName.equals(that.tableName))
          return false;
      }

      boolean this_present_opts = true && this.isSetOpts();
      boolean that_present_opts = true && that.isSetOpts();
      if (this_present_opts || that_present_opts) {
        if (!(this_present_opts && that_present_opts))
          return false;
        if (!this.opts.equals(that.opts))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
      if (isSetLogin())
        hashCode = hashCode * 8191 + login.hashCode();

      hashCode = hashCode * 8191 + ((isSetTableName()) ? 131071 : 524287);
      if (isSetTableName())
        hashCode = hashCode * 8191 + tableName.hashCode();

      hashCode = hashCode * 8191 + ((isSetOpts()) ? 131071 : 524287);
      if (isSetOpts())
        hashCode = hashCode * 8191 + opts.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(createWriter_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLogin()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetTableName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.tableName, other.tableName);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOpts()).compareTo(other.isSetOpts());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOpts()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.opts, other.opts);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("createWriter_args(");
      boolean first = true;

      sb.append("login:");
      if (this.login == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.login, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("tableName:");
      if (this.tableName == null) {
        sb.append("null");
      } else {
        sb.append(this.tableName);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("opts:");
      if (this.opts == null) {
        sb.append("null");
      } else {
        sb.append(this.opts);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
      if (opts != null) {
        opts.validate();
      }
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class createWriter_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public createWriter_argsStandardScheme getScheme() {
        return new createWriter_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // LOGIN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.login = iprot.readBinary();
                struct.setLoginIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // TABLE_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.tableName = iprot.readString();
                struct.setTableNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // OPTS
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.opts = new WriterOptions();
                struct.opts.read(iprot);
                struct.setOptsIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, createWriter_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.login != null) {
          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
          oprot.writeBinary(struct.login);
          oprot.writeFieldEnd();
        }
        if (struct.tableName != null) {
          oprot.writeFieldBegin(TABLE_NAME_FIELD_DESC);
          oprot.writeString(struct.tableName);
          oprot.writeFieldEnd();
        }
        if (struct.opts != null) {
          oprot.writeFieldBegin(OPTS_FIELD_DESC);
          struct.opts.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    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 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 {
        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);
        }
        if (struct.isSetTableName()) {
          optionals.set(1);
        }
        if (struct.isSetOpts()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetLogin()) {
          oprot.writeBinary(struct.login);
        }
        if (struct.isSetTableName()) {
          oprot.writeString(struct.tableName);
        }
        if (struct.isSetOpts()) {
          struct.opts.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, createWriter_args struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.tableName = iprot.readString();
          struct.setTableNameIsSet(true);
        }
        if (incoming.get(2)) {
          struct.opts = new WriterOptions();
          struct.opts.read(iprot);
          struct.setOptsIsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("createWriter_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.STRING, (short)0);
    private static final org.apache.thrift.protocol.TField OUTCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("outch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField OUCH3_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch3", org.apache.thrift.protocol.TType.STRUCT, (short)3);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new createWriter_resultStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new createWriter_resultTupleSchemeFactory();

    public java.lang.String success; // required
    public AccumuloException outch1; // required
    public AccumuloSecurityException ouch2; // required
    public TableNotFoundException ouch3; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      OUTCH1((short)1, "outch1"),
      OUCH2((short)2, "ouch2"),
      OUCH3((short)3, "ouch3");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // OUTCH1
            return OUTCH1;
          case 2: // OUCH2
            return OUCH2;
          case 3: // OUCH3
            return OUCH3;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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.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.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);
    }

    public createWriter_result() {
    }

    public createWriter_result(
      java.lang.String success,
      AccumuloException outch1,
      AccumuloSecurityException ouch2,
      TableNotFoundException ouch3)
    {
      this();
      this.success = success;
      this.outch1 = outch1;
      this.ouch2 = ouch2;
      this.ouch3 = ouch3;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public createWriter_result(createWriter_result other) {
      if (other.isSetSuccess()) {
        this.success = other.success;
      }
      if (other.isSetOutch1()) {
        this.outch1 = new AccumuloException(other.outch1);
      }
      if (other.isSetOuch2()) {
        this.ouch2 = new AccumuloSecurityException(other.ouch2);
      }
      if (other.isSetOuch3()) {
        this.ouch3 = new TableNotFoundException(other.ouch3);
      }
    }

    public createWriter_result deepCopy() {
      return new createWriter_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.outch1 = null;
      this.ouch2 = null;
      this.ouch3 = null;
    }

    public java.lang.String getSuccess() {
      return this.success;
    }

    public createWriter_result setSuccess(java.lang.String success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return this.success != null;
    }

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public AccumuloException getOutch1() {
      return this.outch1;
    }

    public createWriter_result setOutch1(AccumuloException outch1) {
      this.outch1 = outch1;
      return this;
    }

    public void unsetOutch1() {
      this.outch1 = null;
    }

    /** Returns true if field outch1 is set (has been assigned a value) and false otherwise */
    public boolean isSetOutch1() {
      return this.outch1 != null;
    }

    public void setOutch1IsSet(boolean value) {
      if (!value) {
        this.outch1 = null;
      }
    }

    public AccumuloSecurityException getOuch2() {
      return this.ouch2;
    }

    public createWriter_result setOuch2(AccumuloSecurityException ouch2) {
      this.ouch2 = ouch2;
      return this;
    }

    public void unsetOuch2() {
      this.ouch2 = null;
    }

    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch2() {
      return this.ouch2 != null;
    }

    public void setOuch2IsSet(boolean value) {
      if (!value) {
        this.ouch2 = null;
      }
    }

    public TableNotFoundException getOuch3() {
      return this.ouch3;
    }

    public createWriter_result setOuch3(TableNotFoundException ouch3) {
      this.ouch3 = ouch3;
      return this;
    }

    public void unsetOuch3() {
      this.ouch3 = null;
    }

    /** Returns true if field ouch3 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch3() {
      return this.ouch3 != null;
    }

    public void setOuch3IsSet(boolean value) {
      if (!value) {
        this.ouch3 = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.lang.String)value);
        }
        break;

      case OUTCH1:
        if (value == null) {
          unsetOutch1();
        } else {
          setOutch1((AccumuloException)value);
        }
        break;

      case OUCH2:
        if (value == null) {
          unsetOuch2();
        } else {
          setOuch2((AccumuloSecurityException)value);
        }
        break;

      case OUCH3:
        if (value == null) {
          unsetOuch3();
        } else {
          setOuch3((TableNotFoundException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case OUTCH1:
        return getOutch1();

      case OUCH2:
        return getOuch2();

      case OUCH3:
        return getOuch3();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case OUTCH1:
        return isSetOutch1();
      case OUCH2:
        return isSetOuch2();
      case OUCH3:
        return isSetOuch3();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof createWriter_result)
        return this.equals((createWriter_result)that);
      return false;
    }

    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();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_outch1 = true && this.isSetOutch1();
      boolean that_present_outch1 = true && that.isSetOutch1();
      if (this_present_outch1 || that_present_outch1) {
        if (!(this_present_outch1 && that_present_outch1))
          return false;
        if (!this.outch1.equals(that.outch1))
          return false;
      }

      boolean this_present_ouch2 = true && this.isSetOuch2();
      boolean that_present_ouch2 = true && that.isSetOuch2();
      if (this_present_ouch2 || that_present_ouch2) {
        if (!(this_present_ouch2 && that_present_ouch2))
          return false;
        if (!this.ouch2.equals(that.ouch2))
          return false;
      }

      boolean this_present_ouch3 = true && this.isSetOuch3();
      boolean that_present_ouch3 = true && that.isSetOuch3();
      if (this_present_ouch3 || that_present_ouch3) {
        if (!(this_present_ouch3 && that_present_ouch3))
          return false;
        if (!this.ouch3.equals(that.ouch3))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
      if (isSetSuccess())
        hashCode = hashCode * 8191 + success.hashCode();

      hashCode = hashCode * 8191 + ((isSetOutch1()) ? 131071 : 524287);
      if (isSetOutch1())
        hashCode = hashCode * 8191 + outch1.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
      if (isSetOuch2())
        hashCode = hashCode * 8191 + ouch2.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
      if (isSetOuch3())
        hashCode = hashCode * 8191 + ouch3.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(createWriter_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOutch1()).compareTo(other.isSetOutch1());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOutch1()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.outch1, other.outch1);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch2()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch3()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch3, other.ouch3);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("createWriter_result(");
      boolean first = true;

      sb.append("success:");
      if (this.success == null) {
        sb.append("null");
      } else {
        sb.append(this.success);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("outch1:");
      if (this.outch1 == null) {
        sb.append("null");
      } else {
        sb.append(this.outch1);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch2:");
      if (this.ouch2 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch2);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch3:");
      if (this.ouch3 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch3);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class createWriter_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public createWriter_resultStandardScheme getScheme() {
        return new createWriter_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.success = iprot.readString();
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // OUTCH1
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.outch1 = new AccumuloException();
                struct.outch1.read(iprot);
                struct.setOutch1IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OUCH2
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch2 = new AccumuloSecurityException();
                struct.ouch2.read(iprot);
                struct.setOuch2IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // OUCH3
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch3 = new TableNotFoundException();
                struct.ouch3.read(iprot);
                struct.setOuch3IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, createWriter_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          oprot.writeString(struct.success);
          oprot.writeFieldEnd();
        }
        if (struct.outch1 != null) {
          oprot.writeFieldBegin(OUTCH1_FIELD_DESC);
          struct.outch1.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch2 != null) {
          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
          struct.ouch2.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch3 != null) {
          oprot.writeFieldBegin(OUCH3_FIELD_DESC);
          struct.ouch3.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class createWriter_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public createWriter_resultTupleScheme getScheme() {
        return new createWriter_resultTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetOutch1()) {
          optionals.set(1);
        }
        if (struct.isSetOuch2()) {
          optionals.set(2);
        }
        if (struct.isSetOuch3()) {
          optionals.set(3);
        }
        oprot.writeBitSet(optionals, 4);
        if (struct.isSetSuccess()) {
          oprot.writeString(struct.success);
        }
        if (struct.isSetOutch1()) {
          struct.outch1.write(oprot);
        }
        if (struct.isSetOuch2()) {
          struct.ouch2.write(oprot);
        }
        if (struct.isSetOuch3()) {
          struct.ouch3.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, createWriter_result struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.outch1 = new AccumuloException();
          struct.outch1.read(iprot);
          struct.setOutch1IsSet(true);
        }
        if (incoming.get(2)) {
          struct.ouch2 = new AccumuloSecurityException();
          struct.ouch2.read(iprot);
          struct.setOuch2IsSet(true);
        }
        if (incoming.get(3)) {
          struct.ouch3 = new TableNotFoundException();
          struct.ouch3.read(iprot);
          struct.setOuch3IsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("update_args");

    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 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 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 java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // WRITER
            return WRITER;
          case 2: // CELLS
            return CELLS;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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, 
          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.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
                  new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, ColumnUpdate.class)))));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(update_args.class, metaDataMap);
    }

    public update_args() {
    }

    public update_args(
      java.lang.String writer,
      java.util.Map<java.nio.ByteBuffer,java.util.List<ColumnUpdate>> cells)
    {
      this();
      this.writer = writer;
      this.cells = cells;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public update_args(update_args other) {
      if (other.isSetWriter()) {
        this.writer = other.writer;
      }
      if (other.isSetCells()) {
        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()) {

          java.nio.ByteBuffer other_element_key = other_element.getKey();
          java.util.List<ColumnUpdate> other_element_value = other_element.getValue();

          java.nio.ByteBuffer __this__cells_copy_key = org.apache.thrift.TBaseHelper.copyBinary(other_element_key);

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

          __this__cells.put(__this__cells_copy_key, __this__cells_copy_value);
        }
        this.cells = __this__cells;
      }
    }

    public update_args deepCopy() {
      return new update_args(this);
    }

    @Override
    public void clear() {
      this.writer = null;
      this.cells = null;
    }

    public java.lang.String getWriter() {
      return this.writer;
    }

    public update_args setWriter(java.lang.String writer) {
      this.writer = writer;
      return this;
    }

    public void unsetWriter() {
      this.writer = null;
    }

    /** Returns true if field writer is set (has been assigned a value) and false otherwise */
    public boolean isSetWriter() {
      return this.writer != null;
    }

    public void setWriterIsSet(boolean value) {
      if (!value) {
        this.writer = null;
      }
    }

    public int getCellsSize() {
      return (this.cells == null) ? 0 : this.cells.size();
    }

    public void putToCells(java.nio.ByteBuffer key, java.util.List<ColumnUpdate> val) {
      if (this.cells == null) {
        this.cells = new java.util.HashMap<java.nio.ByteBuffer,java.util.List<ColumnUpdate>>();
      }
      this.cells.put(key, val);
    }

    public java.util.Map<java.nio.ByteBuffer,java.util.List<ColumnUpdate>> getCells() {
      return this.cells;
    }

    public update_args setCells(java.util.Map<java.nio.ByteBuffer,java.util.List<ColumnUpdate>> cells) {
      this.cells = cells;
      return this;
    }

    public void unsetCells() {
      this.cells = null;
    }

    /** Returns true if field cells is set (has been assigned a value) and false otherwise */
    public boolean isSetCells() {
      return this.cells != null;
    }

    public void setCellsIsSet(boolean value) {
      if (!value) {
        this.cells = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case WRITER:
        if (value == null) {
          unsetWriter();
        } else {
          setWriter((java.lang.String)value);
        }
        break;

      case CELLS:
        if (value == null) {
          unsetCells();
        } else {
          setCells((java.util.Map<java.nio.ByteBuffer,java.util.List<ColumnUpdate>>)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case WRITER:
        return getWriter();

      case CELLS:
        return getCells();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case WRITER:
        return isSetWriter();
      case CELLS:
        return isSetCells();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof update_args)
        return this.equals((update_args)that);
      return false;
    }

    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();
      if (this_present_writer || that_present_writer) {
        if (!(this_present_writer && that_present_writer))
          return false;
        if (!this.writer.equals(that.writer))
          return false;
      }

      boolean this_present_cells = true && this.isSetCells();
      boolean that_present_cells = true && that.isSetCells();
      if (this_present_cells || that_present_cells) {
        if (!(this_present_cells && that_present_cells))
          return false;
        if (!this.cells.equals(that.cells))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetWriter()) ? 131071 : 524287);
      if (isSetWriter())
        hashCode = hashCode * 8191 + writer.hashCode();

      hashCode = hashCode * 8191 + ((isSetCells()) ? 131071 : 524287);
      if (isSetCells())
        hashCode = hashCode * 8191 + cells.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(update_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetWriter()).compareTo(other.isSetWriter());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetWriter()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.writer, other.writer);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetCells()).compareTo(other.isSetCells());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetCells()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.cells, other.cells);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("update_args(");
      boolean first = true;

      sb.append("writer:");
      if (this.writer == null) {
        sb.append("null");
      } else {
        sb.append(this.writer);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("cells:");
      if (this.cells == null) {
        sb.append("null");
      } else {
        sb.append(this.cells);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class update_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public update_argsStandardScheme getScheme() {
        return new update_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // WRITER
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.writer = iprot.readString();
                struct.setWriterIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // CELLS
              if (schemeField.type == org.apache.thrift.protocol.TType.MAP) {
                {
                  org.apache.thrift.protocol.TMap _map460 = iprot.readMapBegin();
                  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 java.util.ArrayList<ColumnUpdate>(_list464.size);
                      ColumnUpdate _elem465;
                      for (int _i466 = 0; _i466 < _list464.size; ++_i466)
                      {
                        _elem465 = new ColumnUpdate();
                        _elem465.read(iprot);
                        _val462.add(_elem465);
                      }
                      iprot.readListEnd();
                    }
                    struct.cells.put(_key461, _val462);
                  }
                  iprot.readMapEnd();
                }
                struct.setCellsIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, update_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.writer != null) {
          oprot.writeFieldBegin(WRITER_FIELD_DESC);
          oprot.writeString(struct.writer);
          oprot.writeFieldEnd();
        }
        if (struct.cells != null) {
          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 (java.util.Map.Entry<java.nio.ByteBuffer, java.util.List<ColumnUpdate>> _iter467 : struct.cells.entrySet())
            {
              oprot.writeBinary(_iter467.getKey());
              {
                oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, _iter467.getValue().size()));
                for (ColumnUpdate _iter468 : _iter467.getValue())
                {
                  _iter468.write(oprot);
                }
                oprot.writeListEnd();
              }
            }
            oprot.writeMapEnd();
          }
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    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 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 {
        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);
        }
        if (struct.isSetCells()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetWriter()) {
          oprot.writeString(struct.writer);
        }
        if (struct.isSetCells()) {
          {
            oprot.writeI32(struct.cells.size());
            for (java.util.Map.Entry<java.nio.ByteBuffer, java.util.List<ColumnUpdate>> _iter469 : struct.cells.entrySet())
            {
              oprot.writeBinary(_iter469.getKey());
              {
                oprot.writeI32(_iter469.getValue().size());
                for (ColumnUpdate _iter470 : _iter469.getValue())
                {
                  _iter470.write(oprot);
                }
              }
            }
          }
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, update_args struct) throws org.apache.thrift.TException {
        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);
        }
        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 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 java.util.ArrayList<ColumnUpdate>(_list475.size);
                ColumnUpdate _elem476;
                for (int _i477 = 0; _i477 < _list475.size; ++_i477)
                {
                  _elem476 = new ColumnUpdate();
                  _elem476.read(iprot);
                  _val473.add(_elem476);
                }
              }
              struct.cells.put(_key472, _val473);
            }
          }
          struct.setCellsIsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("flush_args");

    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.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new flush_argsStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new flush_argsTupleSchemeFactory();

    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 java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // WRITER
            return WRITER;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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 = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(flush_args.class, metaDataMap);
    }

    public flush_args() {
    }

    public flush_args(
      java.lang.String writer)
    {
      this();
      this.writer = writer;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public flush_args(flush_args other) {
      if (other.isSetWriter()) {
        this.writer = other.writer;
      }
    }

    public flush_args deepCopy() {
      return new flush_args(this);
    }

    @Override
    public void clear() {
      this.writer = null;
    }

    public java.lang.String getWriter() {
      return this.writer;
    }

    public flush_args setWriter(java.lang.String writer) {
      this.writer = writer;
      return this;
    }

    public void unsetWriter() {
      this.writer = null;
    }

    /** Returns true if field writer is set (has been assigned a value) and false otherwise */
    public boolean isSetWriter() {
      return this.writer != null;
    }

    public void setWriterIsSet(boolean value) {
      if (!value) {
        this.writer = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case WRITER:
        if (value == null) {
          unsetWriter();
        } else {
          setWriter((java.lang.String)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case WRITER:
        return getWriter();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case WRITER:
        return isSetWriter();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof flush_args)
        return this.equals((flush_args)that);
      return false;
    }

    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();
      if (this_present_writer || that_present_writer) {
        if (!(this_present_writer && that_present_writer))
          return false;
        if (!this.writer.equals(that.writer))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetWriter()) ? 131071 : 524287);
      if (isSetWriter())
        hashCode = hashCode * 8191 + writer.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(flush_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetWriter()).compareTo(other.isSetWriter());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetWriter()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.writer, other.writer);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("flush_args(");
      boolean first = true;

      sb.append("writer:");
      if (this.writer == null) {
        sb.append("null");
      } else {
        sb.append(this.writer);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class flush_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public flush_argsStandardScheme getScheme() {
        return new flush_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // WRITER
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.writer = iprot.readString();
                struct.setWriterIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, flush_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.writer != null) {
          oprot.writeFieldBegin(WRITER_FIELD_DESC);
          oprot.writeString(struct.writer);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    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 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 {
        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);
        }
        oprot.writeBitSet(optionals, 1);
        if (struct.isSetWriter()) {
          oprot.writeString(struct.writer);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, flush_args struct) throws org.apache.thrift.TException {
        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);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("flush_result");

    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);

    private static final org.apache.thrift.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

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      OUCH1((short)1, "ouch1"),
      OUCH2((short)2, "ouch2");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // OUCH1
            return OUCH1;
          case 2: // OUCH2
            return OUCH2;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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.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);
    }

    public flush_result() {
    }

    public flush_result(
      UnknownWriter ouch1,
      MutationsRejectedException ouch2)
    {
      this();
      this.ouch1 = ouch1;
      this.ouch2 = ouch2;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public flush_result(flush_result other) {
      if (other.isSetOuch1()) {
        this.ouch1 = new UnknownWriter(other.ouch1);
      }
      if (other.isSetOuch2()) {
        this.ouch2 = new MutationsRejectedException(other.ouch2);
      }
    }

    public flush_result deepCopy() {
      return new flush_result(this);
    }

    @Override
    public void clear() {
      this.ouch1 = null;
      this.ouch2 = null;
    }

    public UnknownWriter getOuch1() {
      return this.ouch1;
    }

    public flush_result setOuch1(UnknownWriter ouch1) {
      this.ouch1 = ouch1;
      return this;
    }

    public void unsetOuch1() {
      this.ouch1 = null;
    }

    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch1() {
      return this.ouch1 != null;
    }

    public void setOuch1IsSet(boolean value) {
      if (!value) {
        this.ouch1 = null;
      }
    }

    public MutationsRejectedException getOuch2() {
      return this.ouch2;
    }

    public flush_result setOuch2(MutationsRejectedException ouch2) {
      this.ouch2 = ouch2;
      return this;
    }

    public void unsetOuch2() {
      this.ouch2 = null;
    }

    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch2() {
      return this.ouch2 != null;
    }

    public void setOuch2IsSet(boolean value) {
      if (!value) {
        this.ouch2 = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case OUCH1:
        if (value == null) {
          unsetOuch1();
        } else {
          setOuch1((UnknownWriter)value);
        }
        break;

      case OUCH2:
        if (value == null) {
          unsetOuch2();
        } else {
          setOuch2((MutationsRejectedException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case OUCH1:
        return getOuch1();

      case OUCH2:
        return getOuch2();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case OUCH1:
        return isSetOuch1();
      case OUCH2:
        return isSetOuch2();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof flush_result)
        return this.equals((flush_result)that);
      return false;
    }

    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();
      if (this_present_ouch1 || that_present_ouch1) {
        if (!(this_present_ouch1 && that_present_ouch1))
          return false;
        if (!this.ouch1.equals(that.ouch1))
          return false;
      }

      boolean this_present_ouch2 = true && this.isSetOuch2();
      boolean that_present_ouch2 = true && that.isSetOuch2();
      if (this_present_ouch2 || that_present_ouch2) {
        if (!(this_present_ouch2 && that_present_ouch2))
          return false;
        if (!this.ouch2.equals(that.ouch2))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
      if (isSetOuch1())
        hashCode = hashCode * 8191 + ouch1.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
      if (isSetOuch2())
        hashCode = hashCode * 8191 + ouch2.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(flush_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch1()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch2()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("flush_result(");
      boolean first = true;

      sb.append("ouch1:");
      if (this.ouch1 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch1);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch2:");
      if (this.ouch2 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch2);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class flush_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public flush_resultStandardScheme getScheme() {
        return new flush_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // OUCH1
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch1 = new UnknownWriter();
                struct.ouch1.read(iprot);
                struct.setOuch1IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OUCH2
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch2 = new MutationsRejectedException();
                struct.ouch2.read(iprot);
                struct.setOuch2IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, flush_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.ouch1 != null) {
          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
          struct.ouch1.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch2 != null) {
          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
          struct.ouch2.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class flush_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public flush_resultTupleScheme getScheme() {
        return new flush_resultTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetOuch2()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetOuch1()) {
          struct.ouch1.write(oprot);
        }
        if (struct.isSetOuch2()) {
          struct.ouch2.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, flush_result struct) throws org.apache.thrift.TException {
        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);
          struct.setOuch1IsSet(true);
        }
        if (incoming.get(1)) {
          struct.ouch2 = new MutationsRejectedException();
          struct.ouch2.read(iprot);
          struct.setOuch2IsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("closeWriter_args");

    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.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new closeWriter_argsStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new closeWriter_argsTupleSchemeFactory();

    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 java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // WRITER
            return WRITER;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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 = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(closeWriter_args.class, metaDataMap);
    }

    public closeWriter_args() {
    }

    public closeWriter_args(
      java.lang.String writer)
    {
      this();
      this.writer = writer;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public closeWriter_args(closeWriter_args other) {
      if (other.isSetWriter()) {
        this.writer = other.writer;
      }
    }

    public closeWriter_args deepCopy() {
      return new closeWriter_args(this);
    }

    @Override
    public void clear() {
      this.writer = null;
    }

    public java.lang.String getWriter() {
      return this.writer;
    }

    public closeWriter_args setWriter(java.lang.String writer) {
      this.writer = writer;
      return this;
    }

    public void unsetWriter() {
      this.writer = null;
    }

    /** Returns true if field writer is set (has been assigned a value) and false otherwise */
    public boolean isSetWriter() {
      return this.writer != null;
    }

    public void setWriterIsSet(boolean value) {
      if (!value) {
        this.writer = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case WRITER:
        if (value == null) {
          unsetWriter();
        } else {
          setWriter((java.lang.String)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case WRITER:
        return getWriter();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case WRITER:
        return isSetWriter();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof closeWriter_args)
        return this.equals((closeWriter_args)that);
      return false;
    }

    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();
      if (this_present_writer || that_present_writer) {
        if (!(this_present_writer && that_present_writer))
          return false;
        if (!this.writer.equals(that.writer))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetWriter()) ? 131071 : 524287);
      if (isSetWriter())
        hashCode = hashCode * 8191 + writer.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(closeWriter_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetWriter()).compareTo(other.isSetWriter());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetWriter()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.writer, other.writer);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("closeWriter_args(");
      boolean first = true;

      sb.append("writer:");
      if (this.writer == null) {
        sb.append("null");
      } else {
        sb.append(this.writer);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class closeWriter_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public closeWriter_argsStandardScheme getScheme() {
        return new closeWriter_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // WRITER
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.writer = iprot.readString();
                struct.setWriterIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, closeWriter_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.writer != null) {
          oprot.writeFieldBegin(WRITER_FIELD_DESC);
          oprot.writeString(struct.writer);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    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 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 {
        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);
        }
        oprot.writeBitSet(optionals, 1);
        if (struct.isSetWriter()) {
          oprot.writeString(struct.writer);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, closeWriter_args struct) throws org.apache.thrift.TException {
        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);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("closeWriter_result");

    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);

    private static final org.apache.thrift.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

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      OUCH1((short)1, "ouch1"),
      OUCH2((short)2, "ouch2");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // OUCH1
            return OUCH1;
          case 2: // OUCH2
            return OUCH2;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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.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);
    }

    public closeWriter_result() {
    }

    public closeWriter_result(
      UnknownWriter ouch1,
      MutationsRejectedException ouch2)
    {
      this();
      this.ouch1 = ouch1;
      this.ouch2 = ouch2;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public closeWriter_result(closeWriter_result other) {
      if (other.isSetOuch1()) {
        this.ouch1 = new UnknownWriter(other.ouch1);
      }
      if (other.isSetOuch2()) {
        this.ouch2 = new MutationsRejectedException(other.ouch2);
      }
    }

    public closeWriter_result deepCopy() {
      return new closeWriter_result(this);
    }

    @Override
    public void clear() {
      this.ouch1 = null;
      this.ouch2 = null;
    }

    public UnknownWriter getOuch1() {
      return this.ouch1;
    }

    public closeWriter_result setOuch1(UnknownWriter ouch1) {
      this.ouch1 = ouch1;
      return this;
    }

    public void unsetOuch1() {
      this.ouch1 = null;
    }

    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch1() {
      return this.ouch1 != null;
    }

    public void setOuch1IsSet(boolean value) {
      if (!value) {
        this.ouch1 = null;
      }
    }

    public MutationsRejectedException getOuch2() {
      return this.ouch2;
    }

    public closeWriter_result setOuch2(MutationsRejectedException ouch2) {
      this.ouch2 = ouch2;
      return this;
    }

    public void unsetOuch2() {
      this.ouch2 = null;
    }

    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch2() {
      return this.ouch2 != null;
    }

    public void setOuch2IsSet(boolean value) {
      if (!value) {
        this.ouch2 = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case OUCH1:
        if (value == null) {
          unsetOuch1();
        } else {
          setOuch1((UnknownWriter)value);
        }
        break;

      case OUCH2:
        if (value == null) {
          unsetOuch2();
        } else {
          setOuch2((MutationsRejectedException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case OUCH1:
        return getOuch1();

      case OUCH2:
        return getOuch2();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case OUCH1:
        return isSetOuch1();
      case OUCH2:
        return isSetOuch2();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof closeWriter_result)
        return this.equals((closeWriter_result)that);
      return false;
    }

    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();
      if (this_present_ouch1 || that_present_ouch1) {
        if (!(this_present_ouch1 && that_present_ouch1))
          return false;
        if (!this.ouch1.equals(that.ouch1))
          return false;
      }

      boolean this_present_ouch2 = true && this.isSetOuch2();
      boolean that_present_ouch2 = true && that.isSetOuch2();
      if (this_present_ouch2 || that_present_ouch2) {
        if (!(this_present_ouch2 && that_present_ouch2))
          return false;
        if (!this.ouch2.equals(that.ouch2))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
      if (isSetOuch1())
        hashCode = hashCode * 8191 + ouch1.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
      if (isSetOuch2())
        hashCode = hashCode * 8191 + ouch2.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(closeWriter_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch1()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch2()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("closeWriter_result(");
      boolean first = true;

      sb.append("ouch1:");
      if (this.ouch1 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch1);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch2:");
      if (this.ouch2 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch2);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class closeWriter_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public closeWriter_resultStandardScheme getScheme() {
        return new closeWriter_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // OUCH1
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch1 = new UnknownWriter();
                struct.ouch1.read(iprot);
                struct.setOuch1IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OUCH2
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch2 = new MutationsRejectedException();
                struct.ouch2.read(iprot);
                struct.setOuch2IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, closeWriter_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.ouch1 != null) {
          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
          struct.ouch1.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch2 != null) {
          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
          struct.ouch2.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class closeWriter_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public closeWriter_resultTupleScheme getScheme() {
        return new closeWriter_resultTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetOuch2()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetOuch1()) {
          struct.ouch1.write(oprot);
        }
        if (struct.isSetOuch2()) {
          struct.ouch2.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, closeWriter_result struct) throws org.apache.thrift.TException {
        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);
          struct.setOuch1IsSet(true);
        }
        if (incoming.get(1)) {
          struct.ouch2 = new MutationsRejectedException();
          struct.ouch2.read(iprot);
          struct.setOuch2IsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("updateRowConditionally_args");

    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField 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 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 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 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. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      LOGIN((short)1, "login"),
      TABLE_NAME((short)2, "tableName"),
      ROW((short)3, "row"),
      UPDATES((short)4, "updates");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // LOGIN
            return LOGIN;
          case 2: // TABLE_NAME
            return TABLE_NAME;
          case 3: // ROW
            return ROW;
          case 4: // UPDATES
            return UPDATES;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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.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 = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(updateRowConditionally_args.class, metaDataMap);
    }

    public updateRowConditionally_args() {
    }

    public updateRowConditionally_args(
      java.nio.ByteBuffer login,
      java.lang.String tableName,
      java.nio.ByteBuffer row,
      ConditionalUpdates updates)
    {
      this();
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      this.tableName = tableName;
      this.row = org.apache.thrift.TBaseHelper.copyBinary(row);
      this.updates = updates;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public updateRowConditionally_args(updateRowConditionally_args other) {
      if (other.isSetLogin()) {
        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
      }
      if (other.isSetTableName()) {
        this.tableName = other.tableName;
      }
      if (other.isSetRow()) {
        this.row = org.apache.thrift.TBaseHelper.copyBinary(other.row);
      }
      if (other.isSetUpdates()) {
        this.updates = new ConditionalUpdates(other.updates);
      }
    }

    public updateRowConditionally_args deepCopy() {
      return new updateRowConditionally_args(this);
    }

    @Override
    public void clear() {
      this.login = null;
      this.tableName = null;
      this.row = null;
      this.updates = null;
    }

    public byte[] getLogin() {
      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
      return login == null ? null : login.array();
    }

    public java.nio.ByteBuffer bufferForLogin() {
      return org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    public updateRowConditionally_args setLogin(byte[] login) {
      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
      return this;
    }

    public updateRowConditionally_args setLogin(java.nio.ByteBuffer login) {
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      return this;
    }

    public void unsetLogin() {
      this.login = null;
    }

    /** Returns true if field login is set (has been assigned a value) and false otherwise */
    public boolean isSetLogin() {
      return this.login != null;
    }

    public void setLoginIsSet(boolean value) {
      if (!value) {
        this.login = null;
      }
    }

    public java.lang.String getTableName() {
      return this.tableName;
    }

    public updateRowConditionally_args setTableName(java.lang.String tableName) {
      this.tableName = tableName;
      return this;
    }

    public void unsetTableName() {
      this.tableName = null;
    }

    /** Returns true if field tableName is set (has been assigned a value) and false otherwise */
    public boolean isSetTableName() {
      return this.tableName != null;
    }

    public void setTableNameIsSet(boolean value) {
      if (!value) {
        this.tableName = null;
      }
    }

    public byte[] getRow() {
      setRow(org.apache.thrift.TBaseHelper.rightSize(row));
      return row == null ? null : row.array();
    }

    public java.nio.ByteBuffer bufferForRow() {
      return org.apache.thrift.TBaseHelper.copyBinary(row);
    }

    public updateRowConditionally_args setRow(byte[] row) {
      this.row = row == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(row.clone());
      return this;
    }

    public updateRowConditionally_args setRow(java.nio.ByteBuffer row) {
      this.row = org.apache.thrift.TBaseHelper.copyBinary(row);
      return this;
    }

    public void unsetRow() {
      this.row = null;
    }

    /** Returns true if field row is set (has been assigned a value) and false otherwise */
    public boolean isSetRow() {
      return this.row != null;
    }

    public void setRowIsSet(boolean value) {
      if (!value) {
        this.row = null;
      }
    }

    public ConditionalUpdates getUpdates() {
      return this.updates;
    }

    public updateRowConditionally_args setUpdates(ConditionalUpdates updates) {
      this.updates = updates;
      return this;
    }

    public void unsetUpdates() {
      this.updates = null;
    }

    /** Returns true if field updates is set (has been assigned a value) and false otherwise */
    public boolean isSetUpdates() {
      return this.updates != null;
    }

    public void setUpdatesIsSet(boolean value) {
      if (!value) {
        this.updates = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case LOGIN:
        if (value == null) {
          unsetLogin();
        } else {
          if (value instanceof byte[]) {
            setLogin((byte[])value);
          } else {
            setLogin((java.nio.ByteBuffer)value);
          }
        }
        break;

      case TABLE_NAME:
        if (value == null) {
          unsetTableName();
        } else {
          setTableName((java.lang.String)value);
        }
        break;

      case ROW:
        if (value == null) {
          unsetRow();
        } else {
          if (value instanceof byte[]) {
            setRow((byte[])value);
          } else {
            setRow((java.nio.ByteBuffer)value);
          }
        }
        break;

      case UPDATES:
        if (value == null) {
          unsetUpdates();
        } else {
          setUpdates((ConditionalUpdates)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case LOGIN:
        return getLogin();

      case TABLE_NAME:
        return getTableName();

      case ROW:
        return getRow();

      case UPDATES:
        return getUpdates();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case LOGIN:
        return isSetLogin();
      case TABLE_NAME:
        return isSetTableName();
      case ROW:
        return isSetRow();
      case UPDATES:
        return isSetUpdates();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof updateRowConditionally_args)
        return this.equals((updateRowConditionally_args)that);
      return false;
    }

    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();
      if (this_present_login || that_present_login) {
        if (!(this_present_login && that_present_login))
          return false;
        if (!this.login.equals(that.login))
          return false;
      }

      boolean this_present_tableName = true && this.isSetTableName();
      boolean that_present_tableName = true && that.isSetTableName();
      if (this_present_tableName || that_present_tableName) {
        if (!(this_present_tableName && that_present_tableName))
          return false;
        if (!this.tableName.equals(that.tableName))
          return false;
      }

      boolean this_present_row = true && this.isSetRow();
      boolean that_present_row = true && that.isSetRow();
      if (this_present_row || that_present_row) {
        if (!(this_present_row && that_present_row))
          return false;
        if (!this.row.equals(that.row))
          return false;
      }

      boolean this_present_updates = true && this.isSetUpdates();
      boolean that_present_updates = true && that.isSetUpdates();
      if (this_present_updates || that_present_updates) {
        if (!(this_present_updates && that_present_updates))
          return false;
        if (!this.updates.equals(that.updates))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
      if (isSetLogin())
        hashCode = hashCode * 8191 + login.hashCode();

      hashCode = hashCode * 8191 + ((isSetTableName()) ? 131071 : 524287);
      if (isSetTableName())
        hashCode = hashCode * 8191 + tableName.hashCode();

      hashCode = hashCode * 8191 + ((isSetRow()) ? 131071 : 524287);
      if (isSetRow())
        hashCode = hashCode * 8191 + row.hashCode();

      hashCode = hashCode * 8191 + ((isSetUpdates()) ? 131071 : 524287);
      if (isSetUpdates())
        hashCode = hashCode * 8191 + updates.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(updateRowConditionally_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLogin()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetTableName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.tableName, other.tableName);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetRow()).compareTo(other.isSetRow());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetRow()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.row, other.row);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetUpdates()).compareTo(other.isSetUpdates());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetUpdates()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.updates, other.updates);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("updateRowConditionally_args(");
      boolean first = true;

      sb.append("login:");
      if (this.login == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.login, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("tableName:");
      if (this.tableName == null) {
        sb.append("null");
      } else {
        sb.append(this.tableName);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("row:");
      if (this.row == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.row, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("updates:");
      if (this.updates == null) {
        sb.append("null");
      } else {
        sb.append(this.updates);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
      if (updates != null) {
        updates.validate();
      }
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class updateRowConditionally_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public updateRowConditionally_argsStandardScheme getScheme() {
        return new updateRowConditionally_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // LOGIN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.login = iprot.readBinary();
                struct.setLoginIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // TABLE_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.tableName = iprot.readString();
                struct.setTableNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ROW
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.row = iprot.readBinary();
                struct.setRowIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // UPDATES
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.updates = new ConditionalUpdates();
                struct.updates.read(iprot);
                struct.setUpdatesIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, updateRowConditionally_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.login != null) {
          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
          oprot.writeBinary(struct.login);
          oprot.writeFieldEnd();
        }
        if (struct.tableName != null) {
          oprot.writeFieldBegin(TABLE_NAME_FIELD_DESC);
          oprot.writeString(struct.tableName);
          oprot.writeFieldEnd();
        }
        if (struct.row != null) {
          oprot.writeFieldBegin(ROW_FIELD_DESC);
          oprot.writeBinary(struct.row);
          oprot.writeFieldEnd();
        }
        if (struct.updates != null) {
          oprot.writeFieldBegin(UPDATES_FIELD_DESC);
          struct.updates.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    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 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 {
        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);
        }
        if (struct.isSetTableName()) {
          optionals.set(1);
        }
        if (struct.isSetRow()) {
          optionals.set(2);
        }
        if (struct.isSetUpdates()) {
          optionals.set(3);
        }
        oprot.writeBitSet(optionals, 4);
        if (struct.isSetLogin()) {
          oprot.writeBinary(struct.login);
        }
        if (struct.isSetTableName()) {
          oprot.writeString(struct.tableName);
        }
        if (struct.isSetRow()) {
          oprot.writeBinary(struct.row);
        }
        if (struct.isSetUpdates()) {
          struct.updates.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, updateRowConditionally_args struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.tableName = iprot.readString();
          struct.setTableNameIsSet(true);
        }
        if (incoming.get(2)) {
          struct.row = iprot.readBinary();
          struct.setRowIsSet(true);
        }
        if (incoming.get(3)) {
          struct.updates = new ConditionalUpdates();
          struct.updates.read(iprot);
          struct.setUpdatesIsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("updateRowConditionally_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.I32, (short)0);
    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField OUCH3_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch3", org.apache.thrift.protocol.TType.STRUCT, (short)3);

    private static final 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();

    /**
     * 
     * @see ConditionalStatus
     */
    public ConditionalStatus success; // required
    public AccumuloException ouch1; // required
    public AccumuloSecurityException ouch2; // required
    public TableNotFoundException ouch3; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      /**
       * 
       * @see ConditionalStatus
       */
      SUCCESS((short)0, "success"),
      OUCH1((short)1, "ouch1"),
      OUCH2((short)2, "ouch2"),
      OUCH3((short)3, "ouch3");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // OUCH1
            return OUCH1;
          case 2: // OUCH2
            return OUCH2;
          case 3: // OUCH3
            return OUCH3;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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.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.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);
    }

    public updateRowConditionally_result() {
    }

    public updateRowConditionally_result(
      ConditionalStatus success,
      AccumuloException ouch1,
      AccumuloSecurityException ouch2,
      TableNotFoundException ouch3)
    {
      this();
      this.success = success;
      this.ouch1 = ouch1;
      this.ouch2 = ouch2;
      this.ouch3 = ouch3;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public updateRowConditionally_result(updateRowConditionally_result other) {
      if (other.isSetSuccess()) {
        this.success = other.success;
      }
      if (other.isSetOuch1()) {
        this.ouch1 = new AccumuloException(other.ouch1);
      }
      if (other.isSetOuch2()) {
        this.ouch2 = new AccumuloSecurityException(other.ouch2);
      }
      if (other.isSetOuch3()) {
        this.ouch3 = new TableNotFoundException(other.ouch3);
      }
    }

    public updateRowConditionally_result deepCopy() {
      return new updateRowConditionally_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ouch1 = null;
      this.ouch2 = null;
      this.ouch3 = null;
    }

    /**
     * 
     * @see ConditionalStatus
     */
    public ConditionalStatus getSuccess() {
      return this.success;
    }

    /**
     * 
     * @see ConditionalStatus
     */
    public updateRowConditionally_result setSuccess(ConditionalStatus success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return this.success != null;
    }

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public AccumuloException getOuch1() {
      return this.ouch1;
    }

    public updateRowConditionally_result setOuch1(AccumuloException ouch1) {
      this.ouch1 = ouch1;
      return this;
    }

    public void unsetOuch1() {
      this.ouch1 = null;
    }

    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch1() {
      return this.ouch1 != null;
    }

    public void setOuch1IsSet(boolean value) {
      if (!value) {
        this.ouch1 = null;
      }
    }

    public AccumuloSecurityException getOuch2() {
      return this.ouch2;
    }

    public updateRowConditionally_result setOuch2(AccumuloSecurityException ouch2) {
      this.ouch2 = ouch2;
      return this;
    }

    public void unsetOuch2() {
      this.ouch2 = null;
    }

    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch2() {
      return this.ouch2 != null;
    }

    public void setOuch2IsSet(boolean value) {
      if (!value) {
        this.ouch2 = null;
      }
    }

    public TableNotFoundException getOuch3() {
      return this.ouch3;
    }

    public updateRowConditionally_result setOuch3(TableNotFoundException ouch3) {
      this.ouch3 = ouch3;
      return this;
    }

    public void unsetOuch3() {
      this.ouch3 = null;
    }

    /** Returns true if field ouch3 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch3() {
      return this.ouch3 != null;
    }

    public void setOuch3IsSet(boolean value) {
      if (!value) {
        this.ouch3 = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((ConditionalStatus)value);
        }
        break;

      case OUCH1:
        if (value == null) {
          unsetOuch1();
        } else {
          setOuch1((AccumuloException)value);
        }
        break;

      case OUCH2:
        if (value == null) {
          unsetOuch2();
        } else {
          setOuch2((AccumuloSecurityException)value);
        }
        break;

      case OUCH3:
        if (value == null) {
          unsetOuch3();
        } else {
          setOuch3((TableNotFoundException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case OUCH1:
        return getOuch1();

      case OUCH2:
        return getOuch2();

      case OUCH3:
        return getOuch3();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case OUCH1:
        return isSetOuch1();
      case OUCH2:
        return isSetOuch2();
      case OUCH3:
        return isSetOuch3();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof updateRowConditionally_result)
        return this.equals((updateRowConditionally_result)that);
      return false;
    }

    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();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ouch1 = true && this.isSetOuch1();
      boolean that_present_ouch1 = true && that.isSetOuch1();
      if (this_present_ouch1 || that_present_ouch1) {
        if (!(this_present_ouch1 && that_present_ouch1))
          return false;
        if (!this.ouch1.equals(that.ouch1))
          return false;
      }

      boolean this_present_ouch2 = true && this.isSetOuch2();
      boolean that_present_ouch2 = true && that.isSetOuch2();
      if (this_present_ouch2 || that_present_ouch2) {
        if (!(this_present_ouch2 && that_present_ouch2))
          return false;
        if (!this.ouch2.equals(that.ouch2))
          return false;
      }

      boolean this_present_ouch3 = true && this.isSetOuch3();
      boolean that_present_ouch3 = true && that.isSetOuch3();
      if (this_present_ouch3 || that_present_ouch3) {
        if (!(this_present_ouch3 && that_present_ouch3))
          return false;
        if (!this.ouch3.equals(that.ouch3))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
      if (isSetSuccess())
        hashCode = hashCode * 8191 + success.getValue();

      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
      if (isSetOuch1())
        hashCode = hashCode * 8191 + ouch1.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
      if (isSetOuch2())
        hashCode = hashCode * 8191 + ouch2.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
      if (isSetOuch3())
        hashCode = hashCode * 8191 + ouch3.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(updateRowConditionally_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch1()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch2()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch3()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch3, other.ouch3);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("updateRowConditionally_result(");
      boolean first = true;

      sb.append("success:");
      if (this.success == null) {
        sb.append("null");
      } else {
        sb.append(this.success);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch1:");
      if (this.ouch1 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch1);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch2:");
      if (this.ouch2 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch2);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch3:");
      if (this.ouch3 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch3);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class updateRowConditionally_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public updateRowConditionally_resultStandardScheme getScheme() {
        return new updateRowConditionally_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.success = org.apache.accumulo.proxy.thrift.ConditionalStatus.findByValue(iprot.readI32());
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // OUCH1
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch1 = new AccumuloException();
                struct.ouch1.read(iprot);
                struct.setOuch1IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OUCH2
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch2 = new AccumuloSecurityException();
                struct.ouch2.read(iprot);
                struct.setOuch2IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // OUCH3
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch3 = new TableNotFoundException();
                struct.ouch3.read(iprot);
                struct.setOuch3IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, updateRowConditionally_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          oprot.writeI32(struct.success.getValue());
          oprot.writeFieldEnd();
        }
        if (struct.ouch1 != null) {
          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
          struct.ouch1.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch2 != null) {
          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
          struct.ouch2.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch3 != null) {
          oprot.writeFieldBegin(OUCH3_FIELD_DESC);
          struct.ouch3.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class updateRowConditionally_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public updateRowConditionally_resultTupleScheme getScheme() {
        return new updateRowConditionally_resultTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetOuch1()) {
          optionals.set(1);
        }
        if (struct.isSetOuch2()) {
          optionals.set(2);
        }
        if (struct.isSetOuch3()) {
          optionals.set(3);
        }
        oprot.writeBitSet(optionals, 4);
        if (struct.isSetSuccess()) {
          oprot.writeI32(struct.success.getValue());
        }
        if (struct.isSetOuch1()) {
          struct.ouch1.write(oprot);
        }
        if (struct.isSetOuch2()) {
          struct.ouch2.write(oprot);
        }
        if (struct.isSetOuch3()) {
          struct.ouch3.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, updateRowConditionally_result struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.ouch1 = new AccumuloException();
          struct.ouch1.read(iprot);
          struct.setOuch1IsSet(true);
        }
        if (incoming.get(2)) {
          struct.ouch2 = new AccumuloSecurityException();
          struct.ouch2.read(iprot);
          struct.setOuch2IsSet(true);
        }
        if (incoming.get(3)) {
          struct.ouch3 = new TableNotFoundException();
          struct.ouch3.read(iprot);
          struct.setOuch3IsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("createConditionalWriter_args");

    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField 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 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 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. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      LOGIN((short)1, "login"),
      TABLE_NAME((short)2, "tableName"),
      OPTIONS((short)3, "options");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // LOGIN
            return LOGIN;
          case 2: // TABLE_NAME
            return TABLE_NAME;
          case 3: // OPTIONS
            return OPTIONS;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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 = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(createConditionalWriter_args.class, metaDataMap);
    }

    public createConditionalWriter_args() {
    }

    public createConditionalWriter_args(
      java.nio.ByteBuffer login,
      java.lang.String tableName,
      ConditionalWriterOptions options)
    {
      this();
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      this.tableName = tableName;
      this.options = options;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public createConditionalWriter_args(createConditionalWriter_args other) {
      if (other.isSetLogin()) {
        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
      }
      if (other.isSetTableName()) {
        this.tableName = other.tableName;
      }
      if (other.isSetOptions()) {
        this.options = new ConditionalWriterOptions(other.options);
      }
    }

    public createConditionalWriter_args deepCopy() {
      return new createConditionalWriter_args(this);
    }

    @Override
    public void clear() {
      this.login = null;
      this.tableName = null;
      this.options = null;
    }

    public byte[] getLogin() {
      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
      return login == null ? null : login.array();
    }

    public java.nio.ByteBuffer bufferForLogin() {
      return org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    public createConditionalWriter_args setLogin(byte[] login) {
      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
      return this;
    }

    public createConditionalWriter_args setLogin(java.nio.ByteBuffer login) {
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      return this;
    }

    public void unsetLogin() {
      this.login = null;
    }

    /** Returns true if field login is set (has been assigned a value) and false otherwise */
    public boolean isSetLogin() {
      return this.login != null;
    }

    public void setLoginIsSet(boolean value) {
      if (!value) {
        this.login = null;
      }
    }

    public java.lang.String getTableName() {
      return this.tableName;
    }

    public createConditionalWriter_args setTableName(java.lang.String tableName) {
      this.tableName = tableName;
      return this;
    }

    public void unsetTableName() {
      this.tableName = null;
    }

    /** Returns true if field tableName is set (has been assigned a value) and false otherwise */
    public boolean isSetTableName() {
      return this.tableName != null;
    }

    public void setTableNameIsSet(boolean value) {
      if (!value) {
        this.tableName = null;
      }
    }

    public ConditionalWriterOptions getOptions() {
      return this.options;
    }

    public createConditionalWriter_args setOptions(ConditionalWriterOptions options) {
      this.options = options;
      return this;
    }

    public void unsetOptions() {
      this.options = null;
    }

    /** Returns true if field options is set (has been assigned a value) and false otherwise */
    public boolean isSetOptions() {
      return this.options != null;
    }

    public void setOptionsIsSet(boolean value) {
      if (!value) {
        this.options = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case LOGIN:
        if (value == null) {
          unsetLogin();
        } else {
          if (value instanceof byte[]) {
            setLogin((byte[])value);
          } else {
            setLogin((java.nio.ByteBuffer)value);
          }
        }
        break;

      case TABLE_NAME:
        if (value == null) {
          unsetTableName();
        } else {
          setTableName((java.lang.String)value);
        }
        break;

      case OPTIONS:
        if (value == null) {
          unsetOptions();
        } else {
          setOptions((ConditionalWriterOptions)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case LOGIN:
        return getLogin();

      case TABLE_NAME:
        return getTableName();

      case OPTIONS:
        return getOptions();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case LOGIN:
        return isSetLogin();
      case TABLE_NAME:
        return isSetTableName();
      case OPTIONS:
        return isSetOptions();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof createConditionalWriter_args)
        return this.equals((createConditionalWriter_args)that);
      return false;
    }

    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();
      if (this_present_login || that_present_login) {
        if (!(this_present_login && that_present_login))
          return false;
        if (!this.login.equals(that.login))
          return false;
      }

      boolean this_present_tableName = true && this.isSetTableName();
      boolean that_present_tableName = true && that.isSetTableName();
      if (this_present_tableName || that_present_tableName) {
        if (!(this_present_tableName && that_present_tableName))
          return false;
        if (!this.tableName.equals(that.tableName))
          return false;
      }

      boolean this_present_options = true && this.isSetOptions();
      boolean that_present_options = true && that.isSetOptions();
      if (this_present_options || that_present_options) {
        if (!(this_present_options && that_present_options))
          return false;
        if (!this.options.equals(that.options))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
      if (isSetLogin())
        hashCode = hashCode * 8191 + login.hashCode();

      hashCode = hashCode * 8191 + ((isSetTableName()) ? 131071 : 524287);
      if (isSetTableName())
        hashCode = hashCode * 8191 + tableName.hashCode();

      hashCode = hashCode * 8191 + ((isSetOptions()) ? 131071 : 524287);
      if (isSetOptions())
        hashCode = hashCode * 8191 + options.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(createConditionalWriter_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLogin()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetTableName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.tableName, other.tableName);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOptions()).compareTo(other.isSetOptions());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOptions()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.options, other.options);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("createConditionalWriter_args(");
      boolean first = true;

      sb.append("login:");
      if (this.login == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.login, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("tableName:");
      if (this.tableName == null) {
        sb.append("null");
      } else {
        sb.append(this.tableName);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("options:");
      if (this.options == null) {
        sb.append("null");
      } else {
        sb.append(this.options);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
      if (options != null) {
        options.validate();
      }
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class createConditionalWriter_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public createConditionalWriter_argsStandardScheme getScheme() {
        return new createConditionalWriter_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // LOGIN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.login = iprot.readBinary();
                struct.setLoginIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // TABLE_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.tableName = iprot.readString();
                struct.setTableNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // OPTIONS
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.options = new ConditionalWriterOptions();
                struct.options.read(iprot);
                struct.setOptionsIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, createConditionalWriter_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.login != null) {
          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
          oprot.writeBinary(struct.login);
          oprot.writeFieldEnd();
        }
        if (struct.tableName != null) {
          oprot.writeFieldBegin(TABLE_NAME_FIELD_DESC);
          oprot.writeString(struct.tableName);
          oprot.writeFieldEnd();
        }
        if (struct.options != null) {
          oprot.writeFieldBegin(OPTIONS_FIELD_DESC);
          struct.options.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    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 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 {
        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);
        }
        if (struct.isSetTableName()) {
          optionals.set(1);
        }
        if (struct.isSetOptions()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetLogin()) {
          oprot.writeBinary(struct.login);
        }
        if (struct.isSetTableName()) {
          oprot.writeString(struct.tableName);
        }
        if (struct.isSetOptions()) {
          struct.options.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, createConditionalWriter_args struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.tableName = iprot.readString();
          struct.setTableNameIsSet(true);
        }
        if (incoming.get(2)) {
          struct.options = new ConditionalWriterOptions();
          struct.options.read(iprot);
          struct.setOptionsIsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("createConditionalWriter_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.STRING, (short)0);
    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField OUCH3_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch3", org.apache.thrift.protocol.TType.STRUCT, (short)3);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new createConditionalWriter_resultStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new createConditionalWriter_resultTupleSchemeFactory();

    public java.lang.String success; // required
    public AccumuloException ouch1; // required
    public AccumuloSecurityException ouch2; // required
    public TableNotFoundException ouch3; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      OUCH1((short)1, "ouch1"),
      OUCH2((short)2, "ouch2"),
      OUCH3((short)3, "ouch3");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // OUCH1
            return OUCH1;
          case 2: // OUCH2
            return OUCH2;
          case 3: // OUCH3
            return OUCH3;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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.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.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);
    }

    public createConditionalWriter_result() {
    }

    public createConditionalWriter_result(
      java.lang.String success,
      AccumuloException ouch1,
      AccumuloSecurityException ouch2,
      TableNotFoundException ouch3)
    {
      this();
      this.success = success;
      this.ouch1 = ouch1;
      this.ouch2 = ouch2;
      this.ouch3 = ouch3;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public createConditionalWriter_result(createConditionalWriter_result other) {
      if (other.isSetSuccess()) {
        this.success = other.success;
      }
      if (other.isSetOuch1()) {
        this.ouch1 = new AccumuloException(other.ouch1);
      }
      if (other.isSetOuch2()) {
        this.ouch2 = new AccumuloSecurityException(other.ouch2);
      }
      if (other.isSetOuch3()) {
        this.ouch3 = new TableNotFoundException(other.ouch3);
      }
    }

    public createConditionalWriter_result deepCopy() {
      return new createConditionalWriter_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ouch1 = null;
      this.ouch2 = null;
      this.ouch3 = null;
    }

    public java.lang.String getSuccess() {
      return this.success;
    }

    public createConditionalWriter_result setSuccess(java.lang.String success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return this.success != null;
    }

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public AccumuloException getOuch1() {
      return this.ouch1;
    }

    public createConditionalWriter_result setOuch1(AccumuloException ouch1) {
      this.ouch1 = ouch1;
      return this;
    }

    public void unsetOuch1() {
      this.ouch1 = null;
    }

    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch1() {
      return this.ouch1 != null;
    }

    public void setOuch1IsSet(boolean value) {
      if (!value) {
        this.ouch1 = null;
      }
    }

    public AccumuloSecurityException getOuch2() {
      return this.ouch2;
    }

    public createConditionalWriter_result setOuch2(AccumuloSecurityException ouch2) {
      this.ouch2 = ouch2;
      return this;
    }

    public void unsetOuch2() {
      this.ouch2 = null;
    }

    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch2() {
      return this.ouch2 != null;
    }

    public void setOuch2IsSet(boolean value) {
      if (!value) {
        this.ouch2 = null;
      }
    }

    public TableNotFoundException getOuch3() {
      return this.ouch3;
    }

    public createConditionalWriter_result setOuch3(TableNotFoundException ouch3) {
      this.ouch3 = ouch3;
      return this;
    }

    public void unsetOuch3() {
      this.ouch3 = null;
    }

    /** Returns true if field ouch3 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch3() {
      return this.ouch3 != null;
    }

    public void setOuch3IsSet(boolean value) {
      if (!value) {
        this.ouch3 = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.lang.String)value);
        }
        break;

      case OUCH1:
        if (value == null) {
          unsetOuch1();
        } else {
          setOuch1((AccumuloException)value);
        }
        break;

      case OUCH2:
        if (value == null) {
          unsetOuch2();
        } else {
          setOuch2((AccumuloSecurityException)value);
        }
        break;

      case OUCH3:
        if (value == null) {
          unsetOuch3();
        } else {
          setOuch3((TableNotFoundException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case OUCH1:
        return getOuch1();

      case OUCH2:
        return getOuch2();

      case OUCH3:
        return getOuch3();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case OUCH1:
        return isSetOuch1();
      case OUCH2:
        return isSetOuch2();
      case OUCH3:
        return isSetOuch3();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof createConditionalWriter_result)
        return this.equals((createConditionalWriter_result)that);
      return false;
    }

    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();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ouch1 = true && this.isSetOuch1();
      boolean that_present_ouch1 = true && that.isSetOuch1();
      if (this_present_ouch1 || that_present_ouch1) {
        if (!(this_present_ouch1 && that_present_ouch1))
          return false;
        if (!this.ouch1.equals(that.ouch1))
          return false;
      }

      boolean this_present_ouch2 = true && this.isSetOuch2();
      boolean that_present_ouch2 = true && that.isSetOuch2();
      if (this_present_ouch2 || that_present_ouch2) {
        if (!(this_present_ouch2 && that_present_ouch2))
          return false;
        if (!this.ouch2.equals(that.ouch2))
          return false;
      }

      boolean this_present_ouch3 = true && this.isSetOuch3();
      boolean that_present_ouch3 = true && that.isSetOuch3();
      if (this_present_ouch3 || that_present_ouch3) {
        if (!(this_present_ouch3 && that_present_ouch3))
          return false;
        if (!this.ouch3.equals(that.ouch3))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
      if (isSetSuccess())
        hashCode = hashCode * 8191 + success.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
      if (isSetOuch1())
        hashCode = hashCode * 8191 + ouch1.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
      if (isSetOuch2())
        hashCode = hashCode * 8191 + ouch2.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
      if (isSetOuch3())
        hashCode = hashCode * 8191 + ouch3.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(createConditionalWriter_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch1()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch2()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch3()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch3, other.ouch3);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("createConditionalWriter_result(");
      boolean first = true;

      sb.append("success:");
      if (this.success == null) {
        sb.append("null");
      } else {
        sb.append(this.success);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch1:");
      if (this.ouch1 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch1);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch2:");
      if (this.ouch2 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch2);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch3:");
      if (this.ouch3 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch3);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class createConditionalWriter_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public createConditionalWriter_resultStandardScheme getScheme() {
        return new createConditionalWriter_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.success = iprot.readString();
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // OUCH1
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch1 = new AccumuloException();
                struct.ouch1.read(iprot);
                struct.setOuch1IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OUCH2
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch2 = new AccumuloSecurityException();
                struct.ouch2.read(iprot);
                struct.setOuch2IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // OUCH3
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch3 = new TableNotFoundException();
                struct.ouch3.read(iprot);
                struct.setOuch3IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, createConditionalWriter_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          oprot.writeString(struct.success);
          oprot.writeFieldEnd();
        }
        if (struct.ouch1 != null) {
          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
          struct.ouch1.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch2 != null) {
          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
          struct.ouch2.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch3 != null) {
          oprot.writeFieldBegin(OUCH3_FIELD_DESC);
          struct.ouch3.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class createConditionalWriter_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public createConditionalWriter_resultTupleScheme getScheme() {
        return new createConditionalWriter_resultTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetOuch1()) {
          optionals.set(1);
        }
        if (struct.isSetOuch2()) {
          optionals.set(2);
        }
        if (struct.isSetOuch3()) {
          optionals.set(3);
        }
        oprot.writeBitSet(optionals, 4);
        if (struct.isSetSuccess()) {
          oprot.writeString(struct.success);
        }
        if (struct.isSetOuch1()) {
          struct.ouch1.write(oprot);
        }
        if (struct.isSetOuch2()) {
          struct.ouch2.write(oprot);
        }
        if (struct.isSetOuch3()) {
          struct.ouch3.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, createConditionalWriter_result struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.ouch1 = new AccumuloException();
          struct.ouch1.read(iprot);
          struct.setOuch1IsSet(true);
        }
        if (incoming.get(2)) {
          struct.ouch2 = new AccumuloSecurityException();
          struct.ouch2.read(iprot);
          struct.setOuch2IsSet(true);
        }
        if (incoming.get(3)) {
          struct.ouch3 = new TableNotFoundException();
          struct.ouch3.read(iprot);
          struct.setOuch3IsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("updateRowsConditionally_args");

    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 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 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 java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // CONDITIONAL_WRITER
            return CONDITIONAL_WRITER;
          case 2: // UPDATES
            return UPDATES;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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 = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(updateRowsConditionally_args.class, metaDataMap);
    }

    public updateRowsConditionally_args() {
    }

    public updateRowsConditionally_args(
      java.lang.String conditionalWriter,
      java.util.Map<java.nio.ByteBuffer,ConditionalUpdates> updates)
    {
      this();
      this.conditionalWriter = conditionalWriter;
      this.updates = updates;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public updateRowsConditionally_args(updateRowsConditionally_args other) {
      if (other.isSetConditionalWriter()) {
        this.conditionalWriter = other.conditionalWriter;
      }
      if (other.isSetUpdates()) {
        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()) {

          java.nio.ByteBuffer other_element_key = other_element.getKey();
          ConditionalUpdates other_element_value = other_element.getValue();

          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);

          __this__updates.put(__this__updates_copy_key, __this__updates_copy_value);
        }
        this.updates = __this__updates;
      }
    }

    public updateRowsConditionally_args deepCopy() {
      return new updateRowsConditionally_args(this);
    }

    @Override
    public void clear() {
      this.conditionalWriter = null;
      this.updates = null;
    }

    public java.lang.String getConditionalWriter() {
      return this.conditionalWriter;
    }

    public updateRowsConditionally_args setConditionalWriter(java.lang.String conditionalWriter) {
      this.conditionalWriter = conditionalWriter;
      return this;
    }

    public void unsetConditionalWriter() {
      this.conditionalWriter = null;
    }

    /** Returns true if field conditionalWriter is set (has been assigned a value) and false otherwise */
    public boolean isSetConditionalWriter() {
      return this.conditionalWriter != null;
    }

    public void setConditionalWriterIsSet(boolean value) {
      if (!value) {
        this.conditionalWriter = null;
      }
    }

    public int getUpdatesSize() {
      return (this.updates == null) ? 0 : this.updates.size();
    }

    public void putToUpdates(java.nio.ByteBuffer key, ConditionalUpdates val) {
      if (this.updates == null) {
        this.updates = new java.util.HashMap<java.nio.ByteBuffer,ConditionalUpdates>();
      }
      this.updates.put(key, val);
    }

    public java.util.Map<java.nio.ByteBuffer,ConditionalUpdates> getUpdates() {
      return this.updates;
    }

    public updateRowsConditionally_args setUpdates(java.util.Map<java.nio.ByteBuffer,ConditionalUpdates> updates) {
      this.updates = updates;
      return this;
    }

    public void unsetUpdates() {
      this.updates = null;
    }

    /** Returns true if field updates is set (has been assigned a value) and false otherwise */
    public boolean isSetUpdates() {
      return this.updates != null;
    }

    public void setUpdatesIsSet(boolean value) {
      if (!value) {
        this.updates = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case CONDITIONAL_WRITER:
        if (value == null) {
          unsetConditionalWriter();
        } else {
          setConditionalWriter((java.lang.String)value);
        }
        break;

      case UPDATES:
        if (value == null) {
          unsetUpdates();
        } else {
          setUpdates((java.util.Map<java.nio.ByteBuffer,ConditionalUpdates>)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case CONDITIONAL_WRITER:
        return getConditionalWriter();

      case UPDATES:
        return getUpdates();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case CONDITIONAL_WRITER:
        return isSetConditionalWriter();
      case UPDATES:
        return isSetUpdates();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof updateRowsConditionally_args)
        return this.equals((updateRowsConditionally_args)that);
      return false;
    }

    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();
      if (this_present_conditionalWriter || that_present_conditionalWriter) {
        if (!(this_present_conditionalWriter && that_present_conditionalWriter))
          return false;
        if (!this.conditionalWriter.equals(that.conditionalWriter))
          return false;
      }

      boolean this_present_updates = true && this.isSetUpdates();
      boolean that_present_updates = true && that.isSetUpdates();
      if (this_present_updates || that_present_updates) {
        if (!(this_present_updates && that_present_updates))
          return false;
        if (!this.updates.equals(that.updates))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetConditionalWriter()) ? 131071 : 524287);
      if (isSetConditionalWriter())
        hashCode = hashCode * 8191 + conditionalWriter.hashCode();

      hashCode = hashCode * 8191 + ((isSetUpdates()) ? 131071 : 524287);
      if (isSetUpdates())
        hashCode = hashCode * 8191 + updates.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(updateRowsConditionally_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetConditionalWriter()).compareTo(other.isSetConditionalWriter());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetConditionalWriter()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.conditionalWriter, other.conditionalWriter);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetUpdates()).compareTo(other.isSetUpdates());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetUpdates()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.updates, other.updates);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("updateRowsConditionally_args(");
      boolean first = true;

      sb.append("conditionalWriter:");
      if (this.conditionalWriter == null) {
        sb.append("null");
      } else {
        sb.append(this.conditionalWriter);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("updates:");
      if (this.updates == null) {
        sb.append("null");
      } else {
        sb.append(this.updates);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class updateRowsConditionally_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public updateRowsConditionally_argsStandardScheme getScheme() {
        return new updateRowsConditionally_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // CONDITIONAL_WRITER
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.conditionalWriter = iprot.readString();
                struct.setConditionalWriterIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // UPDATES
              if (schemeField.type == org.apache.thrift.protocol.TType.MAP) {
                {
                  org.apache.thrift.protocol.TMap _map478 = iprot.readMapBegin();
                  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)
                  {
                    _key479 = iprot.readBinary();
                    _val480 = new ConditionalUpdates();
                    _val480.read(iprot);
                    struct.updates.put(_key479, _val480);
                  }
                  iprot.readMapEnd();
                }
                struct.setUpdatesIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, updateRowsConditionally_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.conditionalWriter != null) {
          oprot.writeFieldBegin(CONDITIONAL_WRITER_FIELD_DESC);
          oprot.writeString(struct.conditionalWriter);
          oprot.writeFieldEnd();
        }
        if (struct.updates != null) {
          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 (java.util.Map.Entry<java.nio.ByteBuffer, ConditionalUpdates> _iter482 : struct.updates.entrySet())
            {
              oprot.writeBinary(_iter482.getKey());
              _iter482.getValue().write(oprot);
            }
            oprot.writeMapEnd();
          }
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    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 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 {
        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);
        }
        if (struct.isSetUpdates()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetConditionalWriter()) {
          oprot.writeString(struct.conditionalWriter);
        }
        if (struct.isSetUpdates()) {
          {
            oprot.writeI32(struct.updates.size());
            for (java.util.Map.Entry<java.nio.ByteBuffer, ConditionalUpdates> _iter483 : struct.updates.entrySet())
            {
              oprot.writeBinary(_iter483.getKey());
              _iter483.getValue().write(oprot);
            }
          }
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, updateRowsConditionally_args struct) throws org.apache.thrift.TException {
        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);
        }
        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 java.util.HashMap<java.nio.ByteBuffer,ConditionalUpdates>(2*_map484.size);
            java.nio.ByteBuffer _key485;
            ConditionalUpdates _val486;
            for (int _i487 = 0; _i487 < _map484.size; ++_i487)
            {
              _key485 = iprot.readBinary();
              _val486 = new ConditionalUpdates();
              _val486.read(iprot);
              struct.updates.put(_key485, _val486);
            }
          }
          struct.setUpdatesIsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("updateRowsConditionally_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.MAP, (short)0);
    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField OUCH3_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch3", org.apache.thrift.protocol.TType.STRUCT, (short)3);

    private static final 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 java.util.Map<java.nio.ByteBuffer,ConditionalStatus> success; // required
    public UnknownWriter ouch1; // required
    public AccumuloException ouch2; // required
    public AccumuloSecurityException ouch3; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      OUCH1((short)1, "ouch1"),
      OUCH2((short)2, "ouch2"),
      OUCH3((short)3, "ouch3");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // OUCH1
            return OUCH1;
          case 2: // OUCH2
            return OUCH2;
          case 3: // OUCH3
            return OUCH3;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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.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.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);
    }

    public updateRowsConditionally_result() {
    }

    public updateRowsConditionally_result(
      java.util.Map<java.nio.ByteBuffer,ConditionalStatus> success,
      UnknownWriter ouch1,
      AccumuloException ouch2,
      AccumuloSecurityException ouch3)
    {
      this();
      this.success = success;
      this.ouch1 = ouch1;
      this.ouch2 = ouch2;
      this.ouch3 = ouch3;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public updateRowsConditionally_result(updateRowsConditionally_result other) {
      if (other.isSetSuccess()) {
        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()) {

          java.nio.ByteBuffer other_element_key = other_element.getKey();
          ConditionalStatus other_element_value = other_element.getValue();

          java.nio.ByteBuffer __this__success_copy_key = org.apache.thrift.TBaseHelper.copyBinary(other_element_key);

          ConditionalStatus __this__success_copy_value = other_element_value;

          __this__success.put(__this__success_copy_key, __this__success_copy_value);
        }
        this.success = __this__success;
      }
      if (other.isSetOuch1()) {
        this.ouch1 = new UnknownWriter(other.ouch1);
      }
      if (other.isSetOuch2()) {
        this.ouch2 = new AccumuloException(other.ouch2);
      }
      if (other.isSetOuch3()) {
        this.ouch3 = new AccumuloSecurityException(other.ouch3);
      }
    }

    public updateRowsConditionally_result deepCopy() {
      return new updateRowsConditionally_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ouch1 = null;
      this.ouch2 = null;
      this.ouch3 = null;
    }

    public int getSuccessSize() {
      return (this.success == null) ? 0 : this.success.size();
    }

    public void putToSuccess(java.nio.ByteBuffer key, ConditionalStatus val) {
      if (this.success == null) {
        this.success = new java.util.HashMap<java.nio.ByteBuffer,ConditionalStatus>();
      }
      this.success.put(key, val);
    }

    public java.util.Map<java.nio.ByteBuffer,ConditionalStatus> getSuccess() {
      return this.success;
    }

    public updateRowsConditionally_result setSuccess(java.util.Map<java.nio.ByteBuffer,ConditionalStatus> success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return this.success != null;
    }

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public UnknownWriter getOuch1() {
      return this.ouch1;
    }

    public updateRowsConditionally_result setOuch1(UnknownWriter ouch1) {
      this.ouch1 = ouch1;
      return this;
    }

    public void unsetOuch1() {
      this.ouch1 = null;
    }

    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch1() {
      return this.ouch1 != null;
    }

    public void setOuch1IsSet(boolean value) {
      if (!value) {
        this.ouch1 = null;
      }
    }

    public AccumuloException getOuch2() {
      return this.ouch2;
    }

    public updateRowsConditionally_result setOuch2(AccumuloException ouch2) {
      this.ouch2 = ouch2;
      return this;
    }

    public void unsetOuch2() {
      this.ouch2 = null;
    }

    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch2() {
      return this.ouch2 != null;
    }

    public void setOuch2IsSet(boolean value) {
      if (!value) {
        this.ouch2 = null;
      }
    }

    public AccumuloSecurityException getOuch3() {
      return this.ouch3;
    }

    public updateRowsConditionally_result setOuch3(AccumuloSecurityException ouch3) {
      this.ouch3 = ouch3;
      return this;
    }

    public void unsetOuch3() {
      this.ouch3 = null;
    }

    /** Returns true if field ouch3 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch3() {
      return this.ouch3 != null;
    }

    public void setOuch3IsSet(boolean value) {
      if (!value) {
        this.ouch3 = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.util.Map<java.nio.ByteBuffer,ConditionalStatus>)value);
        }
        break;

      case OUCH1:
        if (value == null) {
          unsetOuch1();
        } else {
          setOuch1((UnknownWriter)value);
        }
        break;

      case OUCH2:
        if (value == null) {
          unsetOuch2();
        } else {
          setOuch2((AccumuloException)value);
        }
        break;

      case OUCH3:
        if (value == null) {
          unsetOuch3();
        } else {
          setOuch3((AccumuloSecurityException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case OUCH1:
        return getOuch1();

      case OUCH2:
        return getOuch2();

      case OUCH3:
        return getOuch3();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case OUCH1:
        return isSetOuch1();
      case OUCH2:
        return isSetOuch2();
      case OUCH3:
        return isSetOuch3();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof updateRowsConditionally_result)
        return this.equals((updateRowsConditionally_result)that);
      return false;
    }

    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();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ouch1 = true && this.isSetOuch1();
      boolean that_present_ouch1 = true && that.isSetOuch1();
      if (this_present_ouch1 || that_present_ouch1) {
        if (!(this_present_ouch1 && that_present_ouch1))
          return false;
        if (!this.ouch1.equals(that.ouch1))
          return false;
      }

      boolean this_present_ouch2 = true && this.isSetOuch2();
      boolean that_present_ouch2 = true && that.isSetOuch2();
      if (this_present_ouch2 || that_present_ouch2) {
        if (!(this_present_ouch2 && that_present_ouch2))
          return false;
        if (!this.ouch2.equals(that.ouch2))
          return false;
      }

      boolean this_present_ouch3 = true && this.isSetOuch3();
      boolean that_present_ouch3 = true && that.isSetOuch3();
      if (this_present_ouch3 || that_present_ouch3) {
        if (!(this_present_ouch3 && that_present_ouch3))
          return false;
        if (!this.ouch3.equals(that.ouch3))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
      if (isSetSuccess())
        hashCode = hashCode * 8191 + success.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
      if (isSetOuch1())
        hashCode = hashCode * 8191 + ouch1.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
      if (isSetOuch2())
        hashCode = hashCode * 8191 + ouch2.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
      if (isSetOuch3())
        hashCode = hashCode * 8191 + ouch3.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(updateRowsConditionally_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch1()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch2()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch3()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch3, other.ouch3);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("updateRowsConditionally_result(");
      boolean first = true;

      sb.append("success:");
      if (this.success == null) {
        sb.append("null");
      } else {
        sb.append(this.success);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch1:");
      if (this.ouch1 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch1);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch2:");
      if (this.ouch2 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch2);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch3:");
      if (this.ouch3 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch3);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class updateRowsConditionally_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public updateRowsConditionally_resultStandardScheme getScheme() {
        return new updateRowsConditionally_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.MAP) {
                {
                  org.apache.thrift.protocol.TMap _map488 = iprot.readMapBegin();
                  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)
                  {
                    _key489 = iprot.readBinary();
                    _val490 = org.apache.accumulo.proxy.thrift.ConditionalStatus.findByValue(iprot.readI32());
                    struct.success.put(_key489, _val490);
                  }
                  iprot.readMapEnd();
                }
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // OUCH1
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch1 = new UnknownWriter();
                struct.ouch1.read(iprot);
                struct.setOuch1IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OUCH2
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch2 = new AccumuloException();
                struct.ouch2.read(iprot);
                struct.setOuch2IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // OUCH3
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch3 = new AccumuloSecurityException();
                struct.ouch3.read(iprot);
                struct.setOuch3IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, updateRowsConditionally_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          {
            oprot.writeMapBegin(new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.I32, struct.success.size()));
            for (java.util.Map.Entry<java.nio.ByteBuffer, ConditionalStatus> _iter492 : struct.success.entrySet())
            {
              oprot.writeBinary(_iter492.getKey());
              oprot.writeI32(_iter492.getValue().getValue());
            }
            oprot.writeMapEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.ouch1 != null) {
          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
          struct.ouch1.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch2 != null) {
          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
          struct.ouch2.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch3 != null) {
          oprot.writeFieldBegin(OUCH3_FIELD_DESC);
          struct.ouch3.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class updateRowsConditionally_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public updateRowsConditionally_resultTupleScheme getScheme() {
        return new updateRowsConditionally_resultTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetOuch1()) {
          optionals.set(1);
        }
        if (struct.isSetOuch2()) {
          optionals.set(2);
        }
        if (struct.isSetOuch3()) {
          optionals.set(3);
        }
        oprot.writeBitSet(optionals, 4);
        if (struct.isSetSuccess()) {
          {
            oprot.writeI32(struct.success.size());
            for (java.util.Map.Entry<java.nio.ByteBuffer, ConditionalStatus> _iter493 : struct.success.entrySet())
            {
              oprot.writeBinary(_iter493.getKey());
              oprot.writeI32(_iter493.getValue().getValue());
            }
          }
        }
        if (struct.isSetOuch1()) {
          struct.ouch1.write(oprot);
        }
        if (struct.isSetOuch2()) {
          struct.ouch2.write(oprot);
        }
        if (struct.isSetOuch3()) {
          struct.ouch3.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, updateRowsConditionally_result struct) throws org.apache.thrift.TException {
        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 java.util.HashMap<java.nio.ByteBuffer,ConditionalStatus>(2*_map494.size);
            java.nio.ByteBuffer _key495;
            ConditionalStatus _val496;
            for (int _i497 = 0; _i497 < _map494.size; ++_i497)
            {
              _key495 = iprot.readBinary();
              _val496 = org.apache.accumulo.proxy.thrift.ConditionalStatus.findByValue(iprot.readI32());
              struct.success.put(_key495, _val496);
            }
          }
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ouch1 = new UnknownWriter();
          struct.ouch1.read(iprot);
          struct.setOuch1IsSet(true);
        }
        if (incoming.get(2)) {
          struct.ouch2 = new AccumuloException();
          struct.ouch2.read(iprot);
          struct.setOuch2IsSet(true);
        }
        if (incoming.get(3)) {
          struct.ouch3 = new AccumuloSecurityException();
          struct.ouch3.read(iprot);
          struct.setOuch3IsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("closeConditionalWriter_args");

    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.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new closeConditionalWriter_argsStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new closeConditionalWriter_argsTupleSchemeFactory();

    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 java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // CONDITIONAL_WRITER
            return CONDITIONAL_WRITER;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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 = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(closeConditionalWriter_args.class, metaDataMap);
    }

    public closeConditionalWriter_args() {
    }

    public closeConditionalWriter_args(
      java.lang.String conditionalWriter)
    {
      this();
      this.conditionalWriter = conditionalWriter;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public closeConditionalWriter_args(closeConditionalWriter_args other) {
      if (other.isSetConditionalWriter()) {
        this.conditionalWriter = other.conditionalWriter;
      }
    }

    public closeConditionalWriter_args deepCopy() {
      return new closeConditionalWriter_args(this);
    }

    @Override
    public void clear() {
      this.conditionalWriter = null;
    }

    public java.lang.String getConditionalWriter() {
      return this.conditionalWriter;
    }

    public closeConditionalWriter_args setConditionalWriter(java.lang.String conditionalWriter) {
      this.conditionalWriter = conditionalWriter;
      return this;
    }

    public void unsetConditionalWriter() {
      this.conditionalWriter = null;
    }

    /** Returns true if field conditionalWriter is set (has been assigned a value) and false otherwise */
    public boolean isSetConditionalWriter() {
      return this.conditionalWriter != null;
    }

    public void setConditionalWriterIsSet(boolean value) {
      if (!value) {
        this.conditionalWriter = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case CONDITIONAL_WRITER:
        if (value == null) {
          unsetConditionalWriter();
        } else {
          setConditionalWriter((java.lang.String)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case CONDITIONAL_WRITER:
        return getConditionalWriter();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case CONDITIONAL_WRITER:
        return isSetConditionalWriter();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof closeConditionalWriter_args)
        return this.equals((closeConditionalWriter_args)that);
      return false;
    }

    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();
      if (this_present_conditionalWriter || that_present_conditionalWriter) {
        if (!(this_present_conditionalWriter && that_present_conditionalWriter))
          return false;
        if (!this.conditionalWriter.equals(that.conditionalWriter))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetConditionalWriter()) ? 131071 : 524287);
      if (isSetConditionalWriter())
        hashCode = hashCode * 8191 + conditionalWriter.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(closeConditionalWriter_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetConditionalWriter()).compareTo(other.isSetConditionalWriter());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetConditionalWriter()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.conditionalWriter, other.conditionalWriter);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("closeConditionalWriter_args(");
      boolean first = true;

      sb.append("conditionalWriter:");
      if (this.conditionalWriter == null) {
        sb.append("null");
      } else {
        sb.append(this.conditionalWriter);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class closeConditionalWriter_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public closeConditionalWriter_argsStandardScheme getScheme() {
        return new closeConditionalWriter_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // CONDITIONAL_WRITER
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.conditionalWriter = iprot.readString();
                struct.setConditionalWriterIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, closeConditionalWriter_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.conditionalWriter != null) {
          oprot.writeFieldBegin(CONDITIONAL_WRITER_FIELD_DESC);
          oprot.writeString(struct.conditionalWriter);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    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 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 {
        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);
        }
        oprot.writeBitSet(optionals, 1);
        if (struct.isSetConditionalWriter()) {
          oprot.writeString(struct.conditionalWriter);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, closeConditionalWriter_args struct) throws org.apache.thrift.TException {
        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);
        }
      }
    }

    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 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 java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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);
    }

    public closeConditionalWriter_result() {
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public closeConditionalWriter_result(closeConditionalWriter_result other) {
    }

    public closeConditionalWriter_result deepCopy() {
      return new closeConditionalWriter_result(this);
    }

    @Override
    public void clear() {
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof closeConditionalWriter_result)
        return this.equals((closeConditionalWriter_result)that);
      return false;
    }

    public boolean equals(closeConditionalWriter_result that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      return hashCode;
    }

    @Override
    public int compareTo(closeConditionalWriter_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("closeConditionalWriter_result(");
      boolean first = true;

      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class closeConditionalWriter_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public closeConditionalWriter_resultStandardScheme getScheme() {
        return new closeConditionalWriter_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, closeConditionalWriter_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    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 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 {
        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 {
        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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getRowRange_args");

    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 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 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 java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // ROW
            return ROW;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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 = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getRowRange_args.class, metaDataMap);
    }

    public getRowRange_args() {
    }

    public getRowRange_args(
      java.nio.ByteBuffer row)
    {
      this();
      this.row = org.apache.thrift.TBaseHelper.copyBinary(row);
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getRowRange_args(getRowRange_args other) {
      if (other.isSetRow()) {
        this.row = org.apache.thrift.TBaseHelper.copyBinary(other.row);
      }
    }

    public getRowRange_args deepCopy() {
      return new getRowRange_args(this);
    }

    @Override
    public void clear() {
      this.row = null;
    }

    public byte[] getRow() {
      setRow(org.apache.thrift.TBaseHelper.rightSize(row));
      return row == null ? null : row.array();
    }

    public java.nio.ByteBuffer bufferForRow() {
      return org.apache.thrift.TBaseHelper.copyBinary(row);
    }

    public getRowRange_args setRow(byte[] row) {
      this.row = row == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(row.clone());
      return this;
    }

    public getRowRange_args setRow(java.nio.ByteBuffer row) {
      this.row = org.apache.thrift.TBaseHelper.copyBinary(row);
      return this;
    }

    public void unsetRow() {
      this.row = null;
    }

    /** Returns true if field row is set (has been assigned a value) and false otherwise */
    public boolean isSetRow() {
      return this.row != null;
    }

    public void setRowIsSet(boolean value) {
      if (!value) {
        this.row = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case ROW:
        if (value == null) {
          unsetRow();
        } else {
          if (value instanceof byte[]) {
            setRow((byte[])value);
          } else {
            setRow((java.nio.ByteBuffer)value);
          }
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case ROW:
        return getRow();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case ROW:
        return isSetRow();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof getRowRange_args)
        return this.equals((getRowRange_args)that);
      return false;
    }

    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();
      if (this_present_row || that_present_row) {
        if (!(this_present_row && that_present_row))
          return false;
        if (!this.row.equals(that.row))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetRow()) ? 131071 : 524287);
      if (isSetRow())
        hashCode = hashCode * 8191 + row.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(getRowRange_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetRow()).compareTo(other.isSetRow());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetRow()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.row, other.row);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("getRowRange_args(");
      boolean first = true;

      sb.append("row:");
      if (this.row == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.row, sb);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class getRowRange_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getRowRange_argsStandardScheme getScheme() {
        return new getRowRange_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // ROW
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.row = iprot.readBinary();
                struct.setRowIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getRowRange_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.row != null) {
          oprot.writeFieldBegin(ROW_FIELD_DESC);
          oprot.writeBinary(struct.row);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    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 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 {
        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);
        }
        oprot.writeBitSet(optionals, 1);
        if (struct.isSetRow()) {
          oprot.writeBinary(struct.row);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getRowRange_args struct) throws org.apache.thrift.TException {
        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);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getRowRange_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.STRUCT, (short)0);

    private static final org.apache.thrift.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

    /** 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 java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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 = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getRowRange_result.class, metaDataMap);
    }

    public getRowRange_result() {
    }

    public getRowRange_result(
      Range success)
    {
      this();
      this.success = success;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getRowRange_result(getRowRange_result other) {
      if (other.isSetSuccess()) {
        this.success = new Range(other.success);
      }
    }

    public getRowRange_result deepCopy() {
      return new getRowRange_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
    }

    public Range getSuccess() {
      return this.success;
    }

    public getRowRange_result setSuccess(Range success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return this.success != null;
    }

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((Range)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof getRowRange_result)
        return this.equals((getRowRange_result)that);
      return false;
    }

    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();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
      if (isSetSuccess())
        hashCode = hashCode * 8191 + success.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(getRowRange_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("getRowRange_result(");
      boolean first = true;

      sb.append("success:");
      if (this.success == null) {
        sb.append("null");
      } else {
        sb.append(this.success);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
      if (success != null) {
        success.validate();
      }
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class getRowRange_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getRowRange_resultStandardScheme getScheme() {
        return new getRowRange_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.success = new Range();
                struct.success.read(iprot);
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getRowRange_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          struct.success.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    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 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 {
        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);
        }
        oprot.writeBitSet(optionals, 1);
        if (struct.isSetSuccess()) {
          struct.success.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getRowRange_result struct) throws org.apache.thrift.TException {
        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);
          struct.setSuccessIsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getFollowing_args");

    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 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
    /**
     * 
     * @see PartialKey
     */
    public PartialKey part; // 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"),
      /**
       * 
       * @see PartialKey
       */
      PART((short)2, "part");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // KEY
            return KEY;
          case 2: // PART
            return PART;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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 = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getFollowing_args.class, metaDataMap);
    }

    public getFollowing_args() {
    }

    public getFollowing_args(
      Key key,
      PartialKey part)
    {
      this();
      this.key = key;
      this.part = part;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getFollowing_args(getFollowing_args other) {
      if (other.isSetKey()) {
        this.key = new Key(other.key);
      }
      if (other.isSetPart()) {
        this.part = other.part;
      }
    }

    public getFollowing_args deepCopy() {
      return new getFollowing_args(this);
    }

    @Override
    public void clear() {
      this.key = null;
      this.part = null;
    }

    public Key getKey() {
      return this.key;
    }

    public getFollowing_args setKey(Key key) {
      this.key = key;
      return this;
    }

    public void unsetKey() {
      this.key = null;
    }

    /** Returns true if field key is set (has been assigned a value) and false otherwise */
    public boolean isSetKey() {
      return this.key != null;
    }

    public void setKeyIsSet(boolean value) {
      if (!value) {
        this.key = null;
      }
    }

    /**
     * 
     * @see PartialKey
     */
    public PartialKey getPart() {
      return this.part;
    }

    /**
     * 
     * @see PartialKey
     */
    public getFollowing_args setPart(PartialKey part) {
      this.part = part;
      return this;
    }

    public void unsetPart() {
      this.part = null;
    }

    /** Returns true if field part is set (has been assigned a value) and false otherwise */
    public boolean isSetPart() {
      return this.part != null;
    }

    public void setPartIsSet(boolean value) {
      if (!value) {
        this.part = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case KEY:
        if (value == null) {
          unsetKey();
        } else {
          setKey((Key)value);
        }
        break;

      case PART:
        if (value == null) {
          unsetPart();
        } else {
          setPart((PartialKey)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case KEY:
        return getKey();

      case PART:
        return getPart();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case KEY:
        return isSetKey();
      case PART:
        return isSetPart();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof getFollowing_args)
        return this.equals((getFollowing_args)that);
      return false;
    }

    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();
      if (this_present_key || that_present_key) {
        if (!(this_present_key && that_present_key))
          return false;
        if (!this.key.equals(that.key))
          return false;
      }

      boolean this_present_part = true && this.isSetPart();
      boolean that_present_part = true && that.isSetPart();
      if (this_present_part || that_present_part) {
        if (!(this_present_part && that_present_part))
          return false;
        if (!this.part.equals(that.part))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetKey()) ? 131071 : 524287);
      if (isSetKey())
        hashCode = hashCode * 8191 + key.hashCode();

      hashCode = hashCode * 8191 + ((isSetPart()) ? 131071 : 524287);
      if (isSetPart())
        hashCode = hashCode * 8191 + part.getValue();

      return hashCode;
    }

    @Override
    public int compareTo(getFollowing_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetKey()).compareTo(other.isSetKey());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetKey()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.key, other.key);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetPart()).compareTo(other.isSetPart());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetPart()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.part, other.part);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("getFollowing_args(");
      boolean first = true;

      sb.append("key:");
      if (this.key == null) {
        sb.append("null");
      } else {
        sb.append(this.key);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("part:");
      if (this.part == null) {
        sb.append("null");
      } else {
        sb.append(this.part);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
      if (key != null) {
        key.validate();
      }
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class getFollowing_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getFollowing_argsStandardScheme getScheme() {
        return new getFollowing_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // KEY
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.key = new Key();
                struct.key.read(iprot);
                struct.setKeyIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // PART
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.part = org.apache.accumulo.proxy.thrift.PartialKey.findByValue(iprot.readI32());
                struct.setPartIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getFollowing_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.key != null) {
          oprot.writeFieldBegin(KEY_FIELD_DESC);
          struct.key.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.part != null) {
          oprot.writeFieldBegin(PART_FIELD_DESC);
          oprot.writeI32(struct.part.getValue());
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    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 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 {
        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);
        }
        if (struct.isSetPart()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetKey()) {
          struct.key.write(oprot);
        }
        if (struct.isSetPart()) {
          oprot.writeI32(struct.part.getValue());
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getFollowing_args struct) throws org.apache.thrift.TException {
        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);
          struct.setKeyIsSet(true);
        }
        if (incoming.get(1)) {
          struct.part = org.apache.accumulo.proxy.thrift.PartialKey.findByValue(iprot.readI32());
          struct.setPartIsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getFollowing_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.STRUCT, (short)0);

    private static final org.apache.thrift.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

    /** 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 java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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 = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getFollowing_result.class, metaDataMap);
    }

    public getFollowing_result() {
    }

    public getFollowing_result(
      Key success)
    {
      this();
      this.success = success;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getFollowing_result(getFollowing_result other) {
      if (other.isSetSuccess()) {
        this.success = new Key(other.success);
      }
    }

    public getFollowing_result deepCopy() {
      return new getFollowing_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
    }

    public Key getSuccess() {
      return this.success;
    }

    public getFollowing_result setSuccess(Key success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return this.success != null;
    }

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((Key)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof getFollowing_result)
        return this.equals((getFollowing_result)that);
      return false;
    }

    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();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
      if (isSetSuccess())
        hashCode = hashCode * 8191 + success.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(getFollowing_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("getFollowing_result(");
      boolean first = true;

      sb.append("success:");
      if (this.success == null) {
        sb.append("null");
      } else {
        sb.append(this.success);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
      if (success != null) {
        success.validate();
      }
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class getFollowing_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getFollowing_resultStandardScheme getScheme() {
        return new getFollowing_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.success = new Key();
                struct.success.read(iprot);
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getFollowing_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          struct.success.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    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 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 {
        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);
        }
        oprot.writeBitSet(optionals, 1);
        if (struct.isSetSuccess()) {
          struct.success.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getFollowing_result struct) throws org.apache.thrift.TException {
        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);
          struct.setSuccessIsSet(true);
        }
      }
    }

    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 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 java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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);
    }

    public systemNamespace_args() {
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public systemNamespace_args(systemNamespace_args other) {
    }

    public systemNamespace_args deepCopy() {
      return new systemNamespace_args(this);
    }

    @Override
    public void clear() {
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof systemNamespace_args)
        return this.equals((systemNamespace_args)that);
      return false;
    }

    public boolean equals(systemNamespace_args that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      return hashCode;
    }

    @Override
    public int compareTo(systemNamespace_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("systemNamespace_args(");
      boolean first = true;

      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class systemNamespace_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public systemNamespace_argsStandardScheme getScheme() {
        return new systemNamespace_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, systemNamespace_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class systemNamespace_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public systemNamespace_argsTupleScheme getScheme() {
        return new systemNamespace_argsTupleScheme();
      }
    }

    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 {
        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 {
        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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("systemNamespace_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.STRING, (short)0);

    private static final 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 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 java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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 = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(systemNamespace_result.class, metaDataMap);
    }

    public systemNamespace_result() {
    }

    public systemNamespace_result(
      java.lang.String success)
    {
      this();
      this.success = success;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public systemNamespace_result(systemNamespace_result other) {
      if (other.isSetSuccess()) {
        this.success = other.success;
      }
    }

    public systemNamespace_result deepCopy() {
      return new systemNamespace_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
    }

    public java.lang.String getSuccess() {
      return this.success;
    }

    public systemNamespace_result setSuccess(java.lang.String success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return this.success != null;
    }

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.lang.String)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof systemNamespace_result)
        return this.equals((systemNamespace_result)that);
      return false;
    }

    public boolean equals(systemNamespace_result that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
      if (isSetSuccess())
        hashCode = hashCode * 8191 + success.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(systemNamespace_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("systemNamespace_result(");
      boolean first = true;

      sb.append("success:");
      if (this.success == null) {
        sb.append("null");
      } else {
        sb.append(this.success);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class systemNamespace_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public systemNamespace_resultStandardScheme getScheme() {
        return new systemNamespace_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.success = iprot.readString();
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, systemNamespace_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          oprot.writeString(struct.success);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class systemNamespace_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public systemNamespace_resultTupleScheme getScheme() {
        return new systemNamespace_resultTupleScheme();
      }
    }

    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 {
        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);
        }
        oprot.writeBitSet(optionals, 1);
        if (struct.isSetSuccess()) {
          oprot.writeString(struct.success);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, systemNamespace_result struct) throws org.apache.thrift.TException {
        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);
        }
      }
    }

    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 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 java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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);
    }

    public defaultNamespace_args() {
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public defaultNamespace_args(defaultNamespace_args other) {
    }

    public defaultNamespace_args deepCopy() {
      return new defaultNamespace_args(this);
    }

    @Override
    public void clear() {
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof defaultNamespace_args)
        return this.equals((defaultNamespace_args)that);
      return false;
    }

    public boolean equals(defaultNamespace_args that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      return hashCode;
    }

    @Override
    public int compareTo(defaultNamespace_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("defaultNamespace_args(");
      boolean first = true;

      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class defaultNamespace_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public defaultNamespace_argsStandardScheme getScheme() {
        return new defaultNamespace_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, defaultNamespace_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class defaultNamespace_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public defaultNamespace_argsTupleScheme getScheme() {
        return new defaultNamespace_argsTupleScheme();
      }
    }

    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 {
        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 {
        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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("defaultNamespace_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.STRING, (short)0);

    private static final 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 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 java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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 = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(defaultNamespace_result.class, metaDataMap);
    }

    public defaultNamespace_result() {
    }

    public defaultNamespace_result(
      java.lang.String success)
    {
      this();
      this.success = success;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public defaultNamespace_result(defaultNamespace_result other) {
      if (other.isSetSuccess()) {
        this.success = other.success;
      }
    }

    public defaultNamespace_result deepCopy() {
      return new defaultNamespace_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
    }

    public java.lang.String getSuccess() {
      return this.success;
    }

    public defaultNamespace_result setSuccess(java.lang.String success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return this.success != null;
    }

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.lang.String)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof defaultNamespace_result)
        return this.equals((defaultNamespace_result)that);
      return false;
    }

    public boolean equals(defaultNamespace_result that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
      if (isSetSuccess())
        hashCode = hashCode * 8191 + success.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(defaultNamespace_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("defaultNamespace_result(");
      boolean first = true;

      sb.append("success:");
      if (this.success == null) {
        sb.append("null");
      } else {
        sb.append(this.success);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class defaultNamespace_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public defaultNamespace_resultStandardScheme getScheme() {
        return new defaultNamespace_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.success = iprot.readString();
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, defaultNamespace_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          oprot.writeString(struct.success);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class defaultNamespace_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public defaultNamespace_resultTupleScheme getScheme() {
        return new defaultNamespace_resultTupleScheme();
      }
    }

    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 {
        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);
        }
        oprot.writeBitSet(optionals, 1);
        if (struct.isSetSuccess()) {
          oprot.writeString(struct.success);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, defaultNamespace_result struct) throws org.apache.thrift.TException {
        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);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("listNamespaces_args");

    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);

    private static final 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 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 java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // LOGIN
            return LOGIN;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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 = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(listNamespaces_args.class, metaDataMap);
    }

    public listNamespaces_args() {
    }

    public listNamespaces_args(
      java.nio.ByteBuffer login)
    {
      this();
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public listNamespaces_args(listNamespaces_args other) {
      if (other.isSetLogin()) {
        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
      }
    }

    public listNamespaces_args deepCopy() {
      return new listNamespaces_args(this);
    }

    @Override
    public void clear() {
      this.login = null;
    }

    public byte[] getLogin() {
      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
      return login == null ? null : login.array();
    }

    public java.nio.ByteBuffer bufferForLogin() {
      return org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    public listNamespaces_args setLogin(byte[] login) {
      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
      return this;
    }

    public listNamespaces_args setLogin(java.nio.ByteBuffer login) {
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      return this;
    }

    public void unsetLogin() {
      this.login = null;
    }

    /** Returns true if field login is set (has been assigned a value) and false otherwise */
    public boolean isSetLogin() {
      return this.login != null;
    }

    public void setLoginIsSet(boolean value) {
      if (!value) {
        this.login = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case LOGIN:
        if (value == null) {
          unsetLogin();
        } else {
          if (value instanceof byte[]) {
            setLogin((byte[])value);
          } else {
            setLogin((java.nio.ByteBuffer)value);
          }
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case LOGIN:
        return getLogin();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case LOGIN:
        return isSetLogin();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof listNamespaces_args)
        return this.equals((listNamespaces_args)that);
      return false;
    }

    public boolean equals(listNamespaces_args that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_login = true && this.isSetLogin();
      boolean that_present_login = true && that.isSetLogin();
      if (this_present_login || that_present_login) {
        if (!(this_present_login && that_present_login))
          return false;
        if (!this.login.equals(that.login))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
      if (isSetLogin())
        hashCode = hashCode * 8191 + login.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(listNamespaces_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLogin()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("listNamespaces_args(");
      boolean first = true;

      sb.append("login:");
      if (this.login == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.login, sb);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class listNamespaces_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public listNamespaces_argsStandardScheme getScheme() {
        return new listNamespaces_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // LOGIN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.login = iprot.readBinary();
                struct.setLoginIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, listNamespaces_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.login != null) {
          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
          oprot.writeBinary(struct.login);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class listNamespaces_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public listNamespaces_argsTupleScheme getScheme() {
        return new listNamespaces_argsTupleScheme();
      }
    }

    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 {
        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);
        }
        oprot.writeBitSet(optionals, 1);
        if (struct.isSetLogin()) {
          oprot.writeBinary(struct.login);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, listNamespaces_args struct) throws org.apache.thrift.TException {
        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);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("listNamespaces_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.LIST, (short)0);
    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);

    private static final 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 java.util.List<java.lang.String> success; // required
    public AccumuloException ouch1; // required
    public AccumuloSecurityException ouch2; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      OUCH1((short)1, "ouch1"),
      OUCH2((short)2, "ouch2");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // OUCH1
            return OUCH1;
          case 2: // OUCH2
            return OUCH2;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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.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);
    }

    public listNamespaces_result() {
    }

    public listNamespaces_result(
      java.util.List<java.lang.String> success,
      AccumuloException ouch1,
      AccumuloSecurityException ouch2)
    {
      this();
      this.success = success;
      this.ouch1 = ouch1;
      this.ouch2 = ouch2;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public listNamespaces_result(listNamespaces_result other) {
      if (other.isSetSuccess()) {
        java.util.List<java.lang.String> __this__success = new java.util.ArrayList<java.lang.String>(other.success);
        this.success = __this__success;
      }
      if (other.isSetOuch1()) {
        this.ouch1 = new AccumuloException(other.ouch1);
      }
      if (other.isSetOuch2()) {
        this.ouch2 = new AccumuloSecurityException(other.ouch2);
      }
    }

    public listNamespaces_result deepCopy() {
      return new listNamespaces_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ouch1 = null;
      this.ouch2 = null;
    }

    public int getSuccessSize() {
      return (this.success == null) ? 0 : this.success.size();
    }

    public java.util.Iterator<java.lang.String> getSuccessIterator() {
      return (this.success == null) ? null : this.success.iterator();
    }

    public void addToSuccess(java.lang.String elem) {
      if (this.success == null) {
        this.success = new java.util.ArrayList<java.lang.String>();
      }
      this.success.add(elem);
    }

    public java.util.List<java.lang.String> getSuccess() {
      return this.success;
    }

    public listNamespaces_result setSuccess(java.util.List<java.lang.String> success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return this.success != null;
    }

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public AccumuloException getOuch1() {
      return this.ouch1;
    }

    public listNamespaces_result setOuch1(AccumuloException ouch1) {
      this.ouch1 = ouch1;
      return this;
    }

    public void unsetOuch1() {
      this.ouch1 = null;
    }

    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch1() {
      return this.ouch1 != null;
    }

    public void setOuch1IsSet(boolean value) {
      if (!value) {
        this.ouch1 = null;
      }
    }

    public AccumuloSecurityException getOuch2() {
      return this.ouch2;
    }

    public listNamespaces_result setOuch2(AccumuloSecurityException ouch2) {
      this.ouch2 = ouch2;
      return this;
    }

    public void unsetOuch2() {
      this.ouch2 = null;
    }

    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch2() {
      return this.ouch2 != null;
    }

    public void setOuch2IsSet(boolean value) {
      if (!value) {
        this.ouch2 = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.util.List<java.lang.String>)value);
        }
        break;

      case OUCH1:
        if (value == null) {
          unsetOuch1();
        } else {
          setOuch1((AccumuloException)value);
        }
        break;

      case OUCH2:
        if (value == null) {
          unsetOuch2();
        } else {
          setOuch2((AccumuloSecurityException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case OUCH1:
        return getOuch1();

      case OUCH2:
        return getOuch2();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case OUCH1:
        return isSetOuch1();
      case OUCH2:
        return isSetOuch2();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof listNamespaces_result)
        return this.equals((listNamespaces_result)that);
      return false;
    }

    public boolean equals(listNamespaces_result that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ouch1 = true && this.isSetOuch1();
      boolean that_present_ouch1 = true && that.isSetOuch1();
      if (this_present_ouch1 || that_present_ouch1) {
        if (!(this_present_ouch1 && that_present_ouch1))
          return false;
        if (!this.ouch1.equals(that.ouch1))
          return false;
      }

      boolean this_present_ouch2 = true && this.isSetOuch2();
      boolean that_present_ouch2 = true && that.isSetOuch2();
      if (this_present_ouch2 || that_present_ouch2) {
        if (!(this_present_ouch2 && that_present_ouch2))
          return false;
        if (!this.ouch2.equals(that.ouch2))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
      if (isSetSuccess())
        hashCode = hashCode * 8191 + success.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
      if (isSetOuch1())
        hashCode = hashCode * 8191 + ouch1.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
      if (isSetOuch2())
        hashCode = hashCode * 8191 + ouch2.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(listNamespaces_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch1()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch2()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("listNamespaces_result(");
      boolean first = true;

      sb.append("success:");
      if (this.success == null) {
        sb.append("null");
      } else {
        sb.append(this.success);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch1:");
      if (this.ouch1 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch1);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch2:");
      if (this.ouch2 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch2);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class listNamespaces_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public listNamespaces_resultStandardScheme getScheme() {
        return new listNamespaces_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
                {
                  org.apache.thrift.protocol.TList _list498 = iprot.readListBegin();
                  struct.success = new java.util.ArrayList<java.lang.String>(_list498.size);
                  java.lang.String _elem499;
                  for (int _i500 = 0; _i500 < _list498.size; ++_i500)
                  {
                    _elem499 = iprot.readString();
                    struct.success.add(_elem499);
                  }
                  iprot.readListEnd();
                }
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // OUCH1
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch1 = new AccumuloException();
                struct.ouch1.read(iprot);
                struct.setOuch1IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OUCH2
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch2 = new AccumuloSecurityException();
                struct.ouch2.read(iprot);
                struct.setOuch2IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, listNamespaces_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRING, struct.success.size()));
            for (java.lang.String _iter501 : struct.success)
            {
              oprot.writeString(_iter501);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.ouch1 != null) {
          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
          struct.ouch1.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch2 != null) {
          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
          struct.ouch2.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class listNamespaces_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public listNamespaces_resultTupleScheme getScheme() {
        return new listNamespaces_resultTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetOuch1()) {
          optionals.set(1);
        }
        if (struct.isSetOuch2()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetSuccess()) {
          {
            oprot.writeI32(struct.success.size());
            for (java.lang.String _iter502 : struct.success)
            {
              oprot.writeString(_iter502);
            }
          }
        }
        if (struct.isSetOuch1()) {
          struct.ouch1.write(oprot);
        }
        if (struct.isSetOuch2()) {
          struct.ouch2.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, listNamespaces_result struct) throws org.apache.thrift.TException {
        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 java.util.ArrayList<java.lang.String>(_list503.size);
            java.lang.String _elem504;
            for (int _i505 = 0; _i505 < _list503.size; ++_i505)
            {
              _elem504 = iprot.readString();
              struct.success.add(_elem504);
            }
          }
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ouch1 = new AccumuloException();
          struct.ouch1.read(iprot);
          struct.setOuch1IsSet(true);
        }
        if (incoming.get(2)) {
          struct.ouch2 = new AccumuloSecurityException();
          struct.ouch2.read(iprot);
          struct.setOuch2IsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("namespaceExists_args");

    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField NAMESPACE_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("namespaceName", org.apache.thrift.protocol.TType.STRING, (short)2);

    private static final 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 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 java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // LOGIN
            return LOGIN;
          case 2: // NAMESPACE_NAME
            return NAMESPACE_NAME;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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 = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(namespaceExists_args.class, metaDataMap);
    }

    public namespaceExists_args() {
    }

    public namespaceExists_args(
      java.nio.ByteBuffer login,
      java.lang.String namespaceName)
    {
      this();
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      this.namespaceName = namespaceName;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public namespaceExists_args(namespaceExists_args other) {
      if (other.isSetLogin()) {
        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
      }
      if (other.isSetNamespaceName()) {
        this.namespaceName = other.namespaceName;
      }
    }

    public namespaceExists_args deepCopy() {
      return new namespaceExists_args(this);
    }

    @Override
    public void clear() {
      this.login = null;
      this.namespaceName = null;
    }

    public byte[] getLogin() {
      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
      return login == null ? null : login.array();
    }

    public java.nio.ByteBuffer bufferForLogin() {
      return org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    public namespaceExists_args setLogin(byte[] login) {
      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
      return this;
    }

    public namespaceExists_args setLogin(java.nio.ByteBuffer login) {
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      return this;
    }

    public void unsetLogin() {
      this.login = null;
    }

    /** Returns true if field login is set (has been assigned a value) and false otherwise */
    public boolean isSetLogin() {
      return this.login != null;
    }

    public void setLoginIsSet(boolean value) {
      if (!value) {
        this.login = null;
      }
    }

    public java.lang.String getNamespaceName() {
      return this.namespaceName;
    }

    public namespaceExists_args setNamespaceName(java.lang.String namespaceName) {
      this.namespaceName = namespaceName;
      return this;
    }

    public void unsetNamespaceName() {
      this.namespaceName = null;
    }

    /** Returns true if field namespaceName is set (has been assigned a value) and false otherwise */
    public boolean isSetNamespaceName() {
      return this.namespaceName != null;
    }

    public void setNamespaceNameIsSet(boolean value) {
      if (!value) {
        this.namespaceName = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case LOGIN:
        if (value == null) {
          unsetLogin();
        } else {
          if (value instanceof byte[]) {
            setLogin((byte[])value);
          } else {
            setLogin((java.nio.ByteBuffer)value);
          }
        }
        break;

      case NAMESPACE_NAME:
        if (value == null) {
          unsetNamespaceName();
        } else {
          setNamespaceName((java.lang.String)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case LOGIN:
        return getLogin();

      case NAMESPACE_NAME:
        return getNamespaceName();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case LOGIN:
        return isSetLogin();
      case NAMESPACE_NAME:
        return isSetNamespaceName();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof namespaceExists_args)
        return this.equals((namespaceExists_args)that);
      return false;
    }

    public boolean equals(namespaceExists_args that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_login = true && this.isSetLogin();
      boolean that_present_login = true && that.isSetLogin();
      if (this_present_login || that_present_login) {
        if (!(this_present_login && that_present_login))
          return false;
        if (!this.login.equals(that.login))
          return false;
      }

      boolean this_present_namespaceName = true && this.isSetNamespaceName();
      boolean that_present_namespaceName = true && that.isSetNamespaceName();
      if (this_present_namespaceName || that_present_namespaceName) {
        if (!(this_present_namespaceName && that_present_namespaceName))
          return false;
        if (!this.namespaceName.equals(that.namespaceName))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
      if (isSetLogin())
        hashCode = hashCode * 8191 + login.hashCode();

      hashCode = hashCode * 8191 + ((isSetNamespaceName()) ? 131071 : 524287);
      if (isSetNamespaceName())
        hashCode = hashCode * 8191 + namespaceName.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(namespaceExists_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLogin()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetNamespaceName()).compareTo(other.isSetNamespaceName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetNamespaceName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.namespaceName, other.namespaceName);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("namespaceExists_args(");
      boolean first = true;

      sb.append("login:");
      if (this.login == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.login, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("namespaceName:");
      if (this.namespaceName == null) {
        sb.append("null");
      } else {
        sb.append(this.namespaceName);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class namespaceExists_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public namespaceExists_argsStandardScheme getScheme() {
        return new namespaceExists_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // LOGIN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.login = iprot.readBinary();
                struct.setLoginIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // NAMESPACE_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.namespaceName = iprot.readString();
                struct.setNamespaceNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, namespaceExists_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.login != null) {
          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
          oprot.writeBinary(struct.login);
          oprot.writeFieldEnd();
        }
        if (struct.namespaceName != null) {
          oprot.writeFieldBegin(NAMESPACE_NAME_FIELD_DESC);
          oprot.writeString(struct.namespaceName);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class namespaceExists_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public namespaceExists_argsTupleScheme getScheme() {
        return new namespaceExists_argsTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetNamespaceName()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetLogin()) {
          oprot.writeBinary(struct.login);
        }
        if (struct.isSetNamespaceName()) {
          oprot.writeString(struct.namespaceName);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, namespaceExists_args struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.namespaceName = iprot.readString();
          struct.setNamespaceNameIsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("namespaceExists_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.BOOL, (short)0);
    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);

    private static final 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
    public AccumuloSecurityException ouch2; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      OUCH1((short)1, "ouch1"),
      OUCH2((short)2, "ouch2");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // OUCH1
            return OUCH1;
          case 2: // OUCH2
            return OUCH2;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __SUCCESS_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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.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);
    }

    public namespaceExists_result() {
    }

    public namespaceExists_result(
      boolean success,
      AccumuloException ouch1,
      AccumuloSecurityException ouch2)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
      this.ouch1 = ouch1;
      this.ouch2 = ouch2;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public namespaceExists_result(namespaceExists_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
      if (other.isSetOuch1()) {
        this.ouch1 = new AccumuloException(other.ouch1);
      }
      if (other.isSetOuch2()) {
        this.ouch2 = new AccumuloSecurityException(other.ouch2);
      }
    }

    public namespaceExists_result deepCopy() {
      return new namespaceExists_result(this);
    }

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
      this.ouch1 = null;
      this.ouch2 = null;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public namespaceExists_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

    public void unsetSuccess() {
      __isset_bitfield = 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 org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    public void setSuccessIsSet(boolean value) {
      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
    }

    public AccumuloException getOuch1() {
      return this.ouch1;
    }

    public namespaceExists_result setOuch1(AccumuloException ouch1) {
      this.ouch1 = ouch1;
      return this;
    }

    public void unsetOuch1() {
      this.ouch1 = null;
    }

    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch1() {
      return this.ouch1 != null;
    }

    public void setOuch1IsSet(boolean value) {
      if (!value) {
        this.ouch1 = null;
      }
    }

    public AccumuloSecurityException getOuch2() {
      return this.ouch2;
    }

    public namespaceExists_result setOuch2(AccumuloSecurityException ouch2) {
      this.ouch2 = ouch2;
      return this;
    }

    public void unsetOuch2() {
      this.ouch2 = null;
    }

    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch2() {
      return this.ouch2 != null;
    }

    public void setOuch2IsSet(boolean value) {
      if (!value) {
        this.ouch2 = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.lang.Boolean)value);
        }
        break;

      case OUCH1:
        if (value == null) {
          unsetOuch1();
        } else {
          setOuch1((AccumuloException)value);
        }
        break;

      case OUCH2:
        if (value == null) {
          unsetOuch2();
        } else {
          setOuch2((AccumuloSecurityException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return isSuccess();

      case OUCH1:
        return getOuch1();

      case OUCH2:
        return getOuch2();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case OUCH1:
        return isSetOuch1();
      case OUCH2:
        return isSetOuch2();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof namespaceExists_result)
        return this.equals((namespaceExists_result)that);
      return false;
    }

    public boolean equals(namespaceExists_result that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_success = true;
      boolean that_present_success = true;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      boolean this_present_ouch1 = true && this.isSetOuch1();
      boolean that_present_ouch1 = true && that.isSetOuch1();
      if (this_present_ouch1 || that_present_ouch1) {
        if (!(this_present_ouch1 && that_present_ouch1))
          return false;
        if (!this.ouch1.equals(that.ouch1))
          return false;
      }

      boolean this_present_ouch2 = true && this.isSetOuch2();
      boolean that_present_ouch2 = true && that.isSetOuch2();
      if (this_present_ouch2 || that_present_ouch2) {
        if (!(this_present_ouch2 && that_present_ouch2))
          return false;
        if (!this.ouch2.equals(that.ouch2))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((success) ? 131071 : 524287);

      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
      if (isSetOuch1())
        hashCode = hashCode * 8191 + ouch1.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
      if (isSetOuch2())
        hashCode = hashCode * 8191 + ouch2.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(namespaceExists_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch1()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch2()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("namespaceExists_result(");
      boolean first = true;

      sb.append("success:");
      sb.append(this.success);
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch1:");
      if (this.ouch1 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch1);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch2:");
      if (this.ouch2 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch2);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, 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;
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class namespaceExists_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public namespaceExists_resultStandardScheme getScheme() {
        return new namespaceExists_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
                struct.success = iprot.readBool();
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // OUCH1
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch1 = new AccumuloException();
                struct.ouch1.read(iprot);
                struct.setOuch1IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OUCH2
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch2 = new AccumuloSecurityException();
                struct.ouch2.read(iprot);
                struct.setOuch2IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, namespaceExists_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.isSetSuccess()) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          oprot.writeBool(struct.success);
          oprot.writeFieldEnd();
        }
        if (struct.ouch1 != null) {
          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
          struct.ouch1.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch2 != null) {
          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
          struct.ouch2.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class namespaceExists_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public namespaceExists_resultTupleScheme getScheme() {
        return new namespaceExists_resultTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetOuch1()) {
          optionals.set(1);
        }
        if (struct.isSetOuch2()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
        if (struct.isSetOuch1()) {
          struct.ouch1.write(oprot);
        }
        if (struct.isSetOuch2()) {
          struct.ouch2.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, namespaceExists_result struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.ouch1 = new AccumuloException();
          struct.ouch1.read(iprot);
          struct.setOuch1IsSet(true);
        }
        if (incoming.get(2)) {
          struct.ouch2 = new AccumuloSecurityException();
          struct.ouch2.read(iprot);
          struct.setOuch2IsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("createNamespace_args");

    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField NAMESPACE_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("namespaceName", org.apache.thrift.protocol.TType.STRING, (short)2);

    private static final 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 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 java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // LOGIN
            return LOGIN;
          case 2: // NAMESPACE_NAME
            return NAMESPACE_NAME;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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 = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(createNamespace_args.class, metaDataMap);
    }

    public createNamespace_args() {
    }

    public createNamespace_args(
      java.nio.ByteBuffer login,
      java.lang.String namespaceName)
    {
      this();
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      this.namespaceName = namespaceName;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public createNamespace_args(createNamespace_args other) {
      if (other.isSetLogin()) {
        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
      }
      if (other.isSetNamespaceName()) {
        this.namespaceName = other.namespaceName;
      }
    }

    public createNamespace_args deepCopy() {
      return new createNamespace_args(this);
    }

    @Override
    public void clear() {
      this.login = null;
      this.namespaceName = null;
    }

    public byte[] getLogin() {
      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
      return login == null ? null : login.array();
    }

    public java.nio.ByteBuffer bufferForLogin() {
      return org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    public createNamespace_args setLogin(byte[] login) {
      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
      return this;
    }

    public createNamespace_args setLogin(java.nio.ByteBuffer login) {
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      return this;
    }

    public void unsetLogin() {
      this.login = null;
    }

    /** Returns true if field login is set (has been assigned a value) and false otherwise */
    public boolean isSetLogin() {
      return this.login != null;
    }

    public void setLoginIsSet(boolean value) {
      if (!value) {
        this.login = null;
      }
    }

    public java.lang.String getNamespaceName() {
      return this.namespaceName;
    }

    public createNamespace_args setNamespaceName(java.lang.String namespaceName) {
      this.namespaceName = namespaceName;
      return this;
    }

    public void unsetNamespaceName() {
      this.namespaceName = null;
    }

    /** Returns true if field namespaceName is set (has been assigned a value) and false otherwise */
    public boolean isSetNamespaceName() {
      return this.namespaceName != null;
    }

    public void setNamespaceNameIsSet(boolean value) {
      if (!value) {
        this.namespaceName = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case LOGIN:
        if (value == null) {
          unsetLogin();
        } else {
          if (value instanceof byte[]) {
            setLogin((byte[])value);
          } else {
            setLogin((java.nio.ByteBuffer)value);
          }
        }
        break;

      case NAMESPACE_NAME:
        if (value == null) {
          unsetNamespaceName();
        } else {
          setNamespaceName((java.lang.String)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case LOGIN:
        return getLogin();

      case NAMESPACE_NAME:
        return getNamespaceName();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case LOGIN:
        return isSetLogin();
      case NAMESPACE_NAME:
        return isSetNamespaceName();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof createNamespace_args)
        return this.equals((createNamespace_args)that);
      return false;
    }

    public boolean equals(createNamespace_args that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_login = true && this.isSetLogin();
      boolean that_present_login = true && that.isSetLogin();
      if (this_present_login || that_present_login) {
        if (!(this_present_login && that_present_login))
          return false;
        if (!this.login.equals(that.login))
          return false;
      }

      boolean this_present_namespaceName = true && this.isSetNamespaceName();
      boolean that_present_namespaceName = true && that.isSetNamespaceName();
      if (this_present_namespaceName || that_present_namespaceName) {
        if (!(this_present_namespaceName && that_present_namespaceName))
          return false;
        if (!this.namespaceName.equals(that.namespaceName))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
      if (isSetLogin())
        hashCode = hashCode * 8191 + login.hashCode();

      hashCode = hashCode * 8191 + ((isSetNamespaceName()) ? 131071 : 524287);
      if (isSetNamespaceName())
        hashCode = hashCode * 8191 + namespaceName.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(createNamespace_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLogin()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetNamespaceName()).compareTo(other.isSetNamespaceName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetNamespaceName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.namespaceName, other.namespaceName);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("createNamespace_args(");
      boolean first = true;

      sb.append("login:");
      if (this.login == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.login, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("namespaceName:");
      if (this.namespaceName == null) {
        sb.append("null");
      } else {
        sb.append(this.namespaceName);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class createNamespace_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public createNamespace_argsStandardScheme getScheme() {
        return new createNamespace_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // LOGIN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.login = iprot.readBinary();
                struct.setLoginIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // NAMESPACE_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.namespaceName = iprot.readString();
                struct.setNamespaceNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, createNamespace_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.login != null) {
          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
          oprot.writeBinary(struct.login);
          oprot.writeFieldEnd();
        }
        if (struct.namespaceName != null) {
          oprot.writeFieldBegin(NAMESPACE_NAME_FIELD_DESC);
          oprot.writeString(struct.namespaceName);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class createNamespace_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public createNamespace_argsTupleScheme getScheme() {
        return new createNamespace_argsTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetNamespaceName()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetLogin()) {
          oprot.writeBinary(struct.login);
        }
        if (struct.isSetNamespaceName()) {
          oprot.writeString(struct.namespaceName);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, createNamespace_args struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.namespaceName = iprot.readString();
          struct.setNamespaceNameIsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("createNamespace_result");

    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField OUCH3_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch3", org.apache.thrift.protocol.TType.STRUCT, (short)3);

    private static final 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
    public NamespaceExistsException ouch3; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      OUCH1((short)1, "ouch1"),
      OUCH2((short)2, "ouch2"),
      OUCH3((short)3, "ouch3");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // OUCH1
            return OUCH1;
          case 2: // OUCH2
            return OUCH2;
          case 3: // OUCH3
            return OUCH3;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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.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.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);
    }

    public createNamespace_result() {
    }

    public createNamespace_result(
      AccumuloException ouch1,
      AccumuloSecurityException ouch2,
      NamespaceExistsException ouch3)
    {
      this();
      this.ouch1 = ouch1;
      this.ouch2 = ouch2;
      this.ouch3 = ouch3;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public createNamespace_result(createNamespace_result other) {
      if (other.isSetOuch1()) {
        this.ouch1 = new AccumuloException(other.ouch1);
      }
      if (other.isSetOuch2()) {
        this.ouch2 = new AccumuloSecurityException(other.ouch2);
      }
      if (other.isSetOuch3()) {
        this.ouch3 = new NamespaceExistsException(other.ouch3);
      }
    }

    public createNamespace_result deepCopy() {
      return new createNamespace_result(this);
    }

    @Override
    public void clear() {
      this.ouch1 = null;
      this.ouch2 = null;
      this.ouch3 = null;
    }

    public AccumuloException getOuch1() {
      return this.ouch1;
    }

    public createNamespace_result setOuch1(AccumuloException ouch1) {
      this.ouch1 = ouch1;
      return this;
    }

    public void unsetOuch1() {
      this.ouch1 = null;
    }

    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch1() {
      return this.ouch1 != null;
    }

    public void setOuch1IsSet(boolean value) {
      if (!value) {
        this.ouch1 = null;
      }
    }

    public AccumuloSecurityException getOuch2() {
      return this.ouch2;
    }

    public createNamespace_result setOuch2(AccumuloSecurityException ouch2) {
      this.ouch2 = ouch2;
      return this;
    }

    public void unsetOuch2() {
      this.ouch2 = null;
    }

    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch2() {
      return this.ouch2 != null;
    }

    public void setOuch2IsSet(boolean value) {
      if (!value) {
        this.ouch2 = null;
      }
    }

    public NamespaceExistsException getOuch3() {
      return this.ouch3;
    }

    public createNamespace_result setOuch3(NamespaceExistsException ouch3) {
      this.ouch3 = ouch3;
      return this;
    }

    public void unsetOuch3() {
      this.ouch3 = null;
    }

    /** Returns true if field ouch3 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch3() {
      return this.ouch3 != null;
    }

    public void setOuch3IsSet(boolean value) {
      if (!value) {
        this.ouch3 = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case OUCH1:
        if (value == null) {
          unsetOuch1();
        } else {
          setOuch1((AccumuloException)value);
        }
        break;

      case OUCH2:
        if (value == null) {
          unsetOuch2();
        } else {
          setOuch2((AccumuloSecurityException)value);
        }
        break;

      case OUCH3:
        if (value == null) {
          unsetOuch3();
        } else {
          setOuch3((NamespaceExistsException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case OUCH1:
        return getOuch1();

      case OUCH2:
        return getOuch2();

      case OUCH3:
        return getOuch3();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case OUCH1:
        return isSetOuch1();
      case OUCH2:
        return isSetOuch2();
      case OUCH3:
        return isSetOuch3();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof createNamespace_result)
        return this.equals((createNamespace_result)that);
      return false;
    }

    public boolean equals(createNamespace_result that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_ouch1 = true && this.isSetOuch1();
      boolean that_present_ouch1 = true && that.isSetOuch1();
      if (this_present_ouch1 || that_present_ouch1) {
        if (!(this_present_ouch1 && that_present_ouch1))
          return false;
        if (!this.ouch1.equals(that.ouch1))
          return false;
      }

      boolean this_present_ouch2 = true && this.isSetOuch2();
      boolean that_present_ouch2 = true && that.isSetOuch2();
      if (this_present_ouch2 || that_present_ouch2) {
        if (!(this_present_ouch2 && that_present_ouch2))
          return false;
        if (!this.ouch2.equals(that.ouch2))
          return false;
      }

      boolean this_present_ouch3 = true && this.isSetOuch3();
      boolean that_present_ouch3 = true && that.isSetOuch3();
      if (this_present_ouch3 || that_present_ouch3) {
        if (!(this_present_ouch3 && that_present_ouch3))
          return false;
        if (!this.ouch3.equals(that.ouch3))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
      if (isSetOuch1())
        hashCode = hashCode * 8191 + ouch1.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
      if (isSetOuch2())
        hashCode = hashCode * 8191 + ouch2.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
      if (isSetOuch3())
        hashCode = hashCode * 8191 + ouch3.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(createNamespace_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch1()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch2()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch3()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch3, other.ouch3);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("createNamespace_result(");
      boolean first = true;

      sb.append("ouch1:");
      if (this.ouch1 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch1);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch2:");
      if (this.ouch2 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch2);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch3:");
      if (this.ouch3 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch3);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class createNamespace_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public createNamespace_resultStandardScheme getScheme() {
        return new createNamespace_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // OUCH1
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch1 = new AccumuloException();
                struct.ouch1.read(iprot);
                struct.setOuch1IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OUCH2
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch2 = new AccumuloSecurityException();
                struct.ouch2.read(iprot);
                struct.setOuch2IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // OUCH3
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch3 = new NamespaceExistsException();
                struct.ouch3.read(iprot);
                struct.setOuch3IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, createNamespace_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.ouch1 != null) {
          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
          struct.ouch1.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch2 != null) {
          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
          struct.ouch2.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch3 != null) {
          oprot.writeFieldBegin(OUCH3_FIELD_DESC);
          struct.ouch3.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class createNamespace_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public createNamespace_resultTupleScheme getScheme() {
        return new createNamespace_resultTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetOuch2()) {
          optionals.set(1);
        }
        if (struct.isSetOuch3()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetOuch1()) {
          struct.ouch1.write(oprot);
        }
        if (struct.isSetOuch2()) {
          struct.ouch2.write(oprot);
        }
        if (struct.isSetOuch3()) {
          struct.ouch3.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, createNamespace_result struct) throws org.apache.thrift.TException {
        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);
          struct.setOuch1IsSet(true);
        }
        if (incoming.get(1)) {
          struct.ouch2 = new AccumuloSecurityException();
          struct.ouch2.read(iprot);
          struct.setOuch2IsSet(true);
        }
        if (incoming.get(2)) {
          struct.ouch3 = new NamespaceExistsException();
          struct.ouch3.read(iprot);
          struct.setOuch3IsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("deleteNamespace_args");

    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField NAMESPACE_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("namespaceName", org.apache.thrift.protocol.TType.STRING, (short)2);

    private static final 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 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 java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // LOGIN
            return LOGIN;
          case 2: // NAMESPACE_NAME
            return NAMESPACE_NAME;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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 = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(deleteNamespace_args.class, metaDataMap);
    }

    public deleteNamespace_args() {
    }

    public deleteNamespace_args(
      java.nio.ByteBuffer login,
      java.lang.String namespaceName)
    {
      this();
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      this.namespaceName = namespaceName;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public deleteNamespace_args(deleteNamespace_args other) {
      if (other.isSetLogin()) {
        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
      }
      if (other.isSetNamespaceName()) {
        this.namespaceName = other.namespaceName;
      }
    }

    public deleteNamespace_args deepCopy() {
      return new deleteNamespace_args(this);
    }

    @Override
    public void clear() {
      this.login = null;
      this.namespaceName = null;
    }

    public byte[] getLogin() {
      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
      return login == null ? null : login.array();
    }

    public java.nio.ByteBuffer bufferForLogin() {
      return org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    public deleteNamespace_args setLogin(byte[] login) {
      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
      return this;
    }

    public deleteNamespace_args setLogin(java.nio.ByteBuffer login) {
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      return this;
    }

    public void unsetLogin() {
      this.login = null;
    }

    /** Returns true if field login is set (has been assigned a value) and false otherwise */
    public boolean isSetLogin() {
      return this.login != null;
    }

    public void setLoginIsSet(boolean value) {
      if (!value) {
        this.login = null;
      }
    }

    public java.lang.String getNamespaceName() {
      return this.namespaceName;
    }

    public deleteNamespace_args setNamespaceName(java.lang.String namespaceName) {
      this.namespaceName = namespaceName;
      return this;
    }

    public void unsetNamespaceName() {
      this.namespaceName = null;
    }

    /** Returns true if field namespaceName is set (has been assigned a value) and false otherwise */
    public boolean isSetNamespaceName() {
      return this.namespaceName != null;
    }

    public void setNamespaceNameIsSet(boolean value) {
      if (!value) {
        this.namespaceName = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case LOGIN:
        if (value == null) {
          unsetLogin();
        } else {
          if (value instanceof byte[]) {
            setLogin((byte[])value);
          } else {
            setLogin((java.nio.ByteBuffer)value);
          }
        }
        break;

      case NAMESPACE_NAME:
        if (value == null) {
          unsetNamespaceName();
        } else {
          setNamespaceName((java.lang.String)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case LOGIN:
        return getLogin();

      case NAMESPACE_NAME:
        return getNamespaceName();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case LOGIN:
        return isSetLogin();
      case NAMESPACE_NAME:
        return isSetNamespaceName();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof deleteNamespace_args)
        return this.equals((deleteNamespace_args)that);
      return false;
    }

    public boolean equals(deleteNamespace_args that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_login = true && this.isSetLogin();
      boolean that_present_login = true && that.isSetLogin();
      if (this_present_login || that_present_login) {
        if (!(this_present_login && that_present_login))
          return false;
        if (!this.login.equals(that.login))
          return false;
      }

      boolean this_present_namespaceName = true && this.isSetNamespaceName();
      boolean that_present_namespaceName = true && that.isSetNamespaceName();
      if (this_present_namespaceName || that_present_namespaceName) {
        if (!(this_present_namespaceName && that_present_namespaceName))
          return false;
        if (!this.namespaceName.equals(that.namespaceName))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
      if (isSetLogin())
        hashCode = hashCode * 8191 + login.hashCode();

      hashCode = hashCode * 8191 + ((isSetNamespaceName()) ? 131071 : 524287);
      if (isSetNamespaceName())
        hashCode = hashCode * 8191 + namespaceName.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(deleteNamespace_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLogin()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetNamespaceName()).compareTo(other.isSetNamespaceName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetNamespaceName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.namespaceName, other.namespaceName);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("deleteNamespace_args(");
      boolean first = true;

      sb.append("login:");
      if (this.login == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.login, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("namespaceName:");
      if (this.namespaceName == null) {
        sb.append("null");
      } else {
        sb.append(this.namespaceName);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class deleteNamespace_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public deleteNamespace_argsStandardScheme getScheme() {
        return new deleteNamespace_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // LOGIN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.login = iprot.readBinary();
                struct.setLoginIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // NAMESPACE_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.namespaceName = iprot.readString();
                struct.setNamespaceNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, deleteNamespace_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.login != null) {
          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
          oprot.writeBinary(struct.login);
          oprot.writeFieldEnd();
        }
        if (struct.namespaceName != null) {
          oprot.writeFieldBegin(NAMESPACE_NAME_FIELD_DESC);
          oprot.writeString(struct.namespaceName);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class deleteNamespace_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public deleteNamespace_argsTupleScheme getScheme() {
        return new deleteNamespace_argsTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetNamespaceName()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetLogin()) {
          oprot.writeBinary(struct.login);
        }
        if (struct.isSetNamespaceName()) {
          oprot.writeString(struct.namespaceName);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, deleteNamespace_args struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.namespaceName = iprot.readString();
          struct.setNamespaceNameIsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("deleteNamespace_result");

    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField OUCH3_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch3", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    private static final org.apache.thrift.protocol.TField OUCH4_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch4", org.apache.thrift.protocol.TType.STRUCT, (short)4);

    private static final 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
    public NamespaceNotFoundException ouch3; // required
    public NamespaceNotEmptyException ouch4; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      OUCH1((short)1, "ouch1"),
      OUCH2((short)2, "ouch2"),
      OUCH3((short)3, "ouch3"),
      OUCH4((short)4, "ouch4");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // OUCH1
            return OUCH1;
          case 2: // OUCH2
            return OUCH2;
          case 3: // OUCH3
            return OUCH3;
          case 4: // OUCH4
            return OUCH4;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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.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.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.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);
    }

    public deleteNamespace_result() {
    }

    public deleteNamespace_result(
      AccumuloException ouch1,
      AccumuloSecurityException ouch2,
      NamespaceNotFoundException ouch3,
      NamespaceNotEmptyException ouch4)
    {
      this();
      this.ouch1 = ouch1;
      this.ouch2 = ouch2;
      this.ouch3 = ouch3;
      this.ouch4 = ouch4;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public deleteNamespace_result(deleteNamespace_result other) {
      if (other.isSetOuch1()) {
        this.ouch1 = new AccumuloException(other.ouch1);
      }
      if (other.isSetOuch2()) {
        this.ouch2 = new AccumuloSecurityException(other.ouch2);
      }
      if (other.isSetOuch3()) {
        this.ouch3 = new NamespaceNotFoundException(other.ouch3);
      }
      if (other.isSetOuch4()) {
        this.ouch4 = new NamespaceNotEmptyException(other.ouch4);
      }
    }

    public deleteNamespace_result deepCopy() {
      return new deleteNamespace_result(this);
    }

    @Override
    public void clear() {
      this.ouch1 = null;
      this.ouch2 = null;
      this.ouch3 = null;
      this.ouch4 = null;
    }

    public AccumuloException getOuch1() {
      return this.ouch1;
    }

    public deleteNamespace_result setOuch1(AccumuloException ouch1) {
      this.ouch1 = ouch1;
      return this;
    }

    public void unsetOuch1() {
      this.ouch1 = null;
    }

    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch1() {
      return this.ouch1 != null;
    }

    public void setOuch1IsSet(boolean value) {
      if (!value) {
        this.ouch1 = null;
      }
    }

    public AccumuloSecurityException getOuch2() {
      return this.ouch2;
    }

    public deleteNamespace_result setOuch2(AccumuloSecurityException ouch2) {
      this.ouch2 = ouch2;
      return this;
    }

    public void unsetOuch2() {
      this.ouch2 = null;
    }

    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch2() {
      return this.ouch2 != null;
    }

    public void setOuch2IsSet(boolean value) {
      if (!value) {
        this.ouch2 = null;
      }
    }

    public NamespaceNotFoundException getOuch3() {
      return this.ouch3;
    }

    public deleteNamespace_result setOuch3(NamespaceNotFoundException ouch3) {
      this.ouch3 = ouch3;
      return this;
    }

    public void unsetOuch3() {
      this.ouch3 = null;
    }

    /** Returns true if field ouch3 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch3() {
      return this.ouch3 != null;
    }

    public void setOuch3IsSet(boolean value) {
      if (!value) {
        this.ouch3 = null;
      }
    }

    public NamespaceNotEmptyException getOuch4() {
      return this.ouch4;
    }

    public deleteNamespace_result setOuch4(NamespaceNotEmptyException ouch4) {
      this.ouch4 = ouch4;
      return this;
    }

    public void unsetOuch4() {
      this.ouch4 = null;
    }

    /** Returns true if field ouch4 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch4() {
      return this.ouch4 != null;
    }

    public void setOuch4IsSet(boolean value) {
      if (!value) {
        this.ouch4 = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case OUCH1:
        if (value == null) {
          unsetOuch1();
        } else {
          setOuch1((AccumuloException)value);
        }
        break;

      case OUCH2:
        if (value == null) {
          unsetOuch2();
        } else {
          setOuch2((AccumuloSecurityException)value);
        }
        break;

      case OUCH3:
        if (value == null) {
          unsetOuch3();
        } else {
          setOuch3((NamespaceNotFoundException)value);
        }
        break;

      case OUCH4:
        if (value == null) {
          unsetOuch4();
        } else {
          setOuch4((NamespaceNotEmptyException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case OUCH1:
        return getOuch1();

      case OUCH2:
        return getOuch2();

      case OUCH3:
        return getOuch3();

      case OUCH4:
        return getOuch4();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case OUCH1:
        return isSetOuch1();
      case OUCH2:
        return isSetOuch2();
      case OUCH3:
        return isSetOuch3();
      case OUCH4:
        return isSetOuch4();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof deleteNamespace_result)
        return this.equals((deleteNamespace_result)that);
      return false;
    }

    public boolean equals(deleteNamespace_result that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_ouch1 = true && this.isSetOuch1();
      boolean that_present_ouch1 = true && that.isSetOuch1();
      if (this_present_ouch1 || that_present_ouch1) {
        if (!(this_present_ouch1 && that_present_ouch1))
          return false;
        if (!this.ouch1.equals(that.ouch1))
          return false;
      }

      boolean this_present_ouch2 = true && this.isSetOuch2();
      boolean that_present_ouch2 = true && that.isSetOuch2();
      if (this_present_ouch2 || that_present_ouch2) {
        if (!(this_present_ouch2 && that_present_ouch2))
          return false;
        if (!this.ouch2.equals(that.ouch2))
          return false;
      }

      boolean this_present_ouch3 = true && this.isSetOuch3();
      boolean that_present_ouch3 = true && that.isSetOuch3();
      if (this_present_ouch3 || that_present_ouch3) {
        if (!(this_present_ouch3 && that_present_ouch3))
          return false;
        if (!this.ouch3.equals(that.ouch3))
          return false;
      }

      boolean this_present_ouch4 = true && this.isSetOuch4();
      boolean that_present_ouch4 = true && that.isSetOuch4();
      if (this_present_ouch4 || that_present_ouch4) {
        if (!(this_present_ouch4 && that_present_ouch4))
          return false;
        if (!this.ouch4.equals(that.ouch4))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
      if (isSetOuch1())
        hashCode = hashCode * 8191 + ouch1.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
      if (isSetOuch2())
        hashCode = hashCode * 8191 + ouch2.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
      if (isSetOuch3())
        hashCode = hashCode * 8191 + ouch3.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch4()) ? 131071 : 524287);
      if (isSetOuch4())
        hashCode = hashCode * 8191 + ouch4.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(deleteNamespace_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch1()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch2()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch3()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch3, other.ouch3);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch4()).compareTo(other.isSetOuch4());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch4()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch4, other.ouch4);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("deleteNamespace_result(");
      boolean first = true;

      sb.append("ouch1:");
      if (this.ouch1 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch1);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch2:");
      if (this.ouch2 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch2);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch3:");
      if (this.ouch3 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch3);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch4:");
      if (this.ouch4 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch4);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class deleteNamespace_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public deleteNamespace_resultStandardScheme getScheme() {
        return new deleteNamespace_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // OUCH1
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch1 = new AccumuloException();
                struct.ouch1.read(iprot);
                struct.setOuch1IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OUCH2
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch2 = new AccumuloSecurityException();
                struct.ouch2.read(iprot);
                struct.setOuch2IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // OUCH3
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch3 = new NamespaceNotFoundException();
                struct.ouch3.read(iprot);
                struct.setOuch3IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // OUCH4
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch4 = new NamespaceNotEmptyException();
                struct.ouch4.read(iprot);
                struct.setOuch4IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, deleteNamespace_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.ouch1 != null) {
          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
          struct.ouch1.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch2 != null) {
          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
          struct.ouch2.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch3 != null) {
          oprot.writeFieldBegin(OUCH3_FIELD_DESC);
          struct.ouch3.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch4 != null) {
          oprot.writeFieldBegin(OUCH4_FIELD_DESC);
          struct.ouch4.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class deleteNamespace_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public deleteNamespace_resultTupleScheme getScheme() {
        return new deleteNamespace_resultTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetOuch2()) {
          optionals.set(1);
        }
        if (struct.isSetOuch3()) {
          optionals.set(2);
        }
        if (struct.isSetOuch4()) {
          optionals.set(3);
        }
        oprot.writeBitSet(optionals, 4);
        if (struct.isSetOuch1()) {
          struct.ouch1.write(oprot);
        }
        if (struct.isSetOuch2()) {
          struct.ouch2.write(oprot);
        }
        if (struct.isSetOuch3()) {
          struct.ouch3.write(oprot);
        }
        if (struct.isSetOuch4()) {
          struct.ouch4.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, deleteNamespace_result struct) throws org.apache.thrift.TException {
        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);
          struct.setOuch1IsSet(true);
        }
        if (incoming.get(1)) {
          struct.ouch2 = new AccumuloSecurityException();
          struct.ouch2.read(iprot);
          struct.setOuch2IsSet(true);
        }
        if (incoming.get(2)) {
          struct.ouch3 = new NamespaceNotFoundException();
          struct.ouch3.read(iprot);
          struct.setOuch3IsSet(true);
        }
        if (incoming.get(3)) {
          struct.ouch4 = new NamespaceNotEmptyException();
          struct.ouch4.read(iprot);
          struct.setOuch4IsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("renameNamespace_args");

    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField OLD_NAMESPACE_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("oldNamespaceName", org.apache.thrift.protocol.TType.STRING, (short)2);
    private static final org.apache.thrift.protocol.TField NEW_NAMESPACE_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("newNamespaceName", org.apache.thrift.protocol.TType.STRING, (short)3);

    private static final 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 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 {
      LOGIN((short)1, "login"),
      OLD_NAMESPACE_NAME((short)2, "oldNamespaceName"),
      NEW_NAMESPACE_NAME((short)3, "newNamespaceName");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // LOGIN
            return LOGIN;
          case 2: // OLD_NAMESPACE_NAME
            return OLD_NAMESPACE_NAME;
          case 3: // NEW_NAMESPACE_NAME
            return NEW_NAMESPACE_NAME;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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 = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(renameNamespace_args.class, metaDataMap);
    }

    public renameNamespace_args() {
    }

    public renameNamespace_args(
      java.nio.ByteBuffer login,
      java.lang.String oldNamespaceName,
      java.lang.String newNamespaceName)
    {
      this();
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      this.oldNamespaceName = oldNamespaceName;
      this.newNamespaceName = newNamespaceName;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public renameNamespace_args(renameNamespace_args other) {
      if (other.isSetLogin()) {
        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
      }
      if (other.isSetOldNamespaceName()) {
        this.oldNamespaceName = other.oldNamespaceName;
      }
      if (other.isSetNewNamespaceName()) {
        this.newNamespaceName = other.newNamespaceName;
      }
    }

    public renameNamespace_args deepCopy() {
      return new renameNamespace_args(this);
    }

    @Override
    public void clear() {
      this.login = null;
      this.oldNamespaceName = null;
      this.newNamespaceName = null;
    }

    public byte[] getLogin() {
      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
      return login == null ? null : login.array();
    }

    public java.nio.ByteBuffer bufferForLogin() {
      return org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    public renameNamespace_args setLogin(byte[] login) {
      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
      return this;
    }

    public renameNamespace_args setLogin(java.nio.ByteBuffer login) {
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      return this;
    }

    public void unsetLogin() {
      this.login = null;
    }

    /** Returns true if field login is set (has been assigned a value) and false otherwise */
    public boolean isSetLogin() {
      return this.login != null;
    }

    public void setLoginIsSet(boolean value) {
      if (!value) {
        this.login = null;
      }
    }

    public java.lang.String getOldNamespaceName() {
      return this.oldNamespaceName;
    }

    public renameNamespace_args setOldNamespaceName(java.lang.String oldNamespaceName) {
      this.oldNamespaceName = oldNamespaceName;
      return this;
    }

    public void unsetOldNamespaceName() {
      this.oldNamespaceName = null;
    }

    /** Returns true if field oldNamespaceName is set (has been assigned a value) and false otherwise */
    public boolean isSetOldNamespaceName() {
      return this.oldNamespaceName != null;
    }

    public void setOldNamespaceNameIsSet(boolean value) {
      if (!value) {
        this.oldNamespaceName = null;
      }
    }

    public java.lang.String getNewNamespaceName() {
      return this.newNamespaceName;
    }

    public renameNamespace_args setNewNamespaceName(java.lang.String newNamespaceName) {
      this.newNamespaceName = newNamespaceName;
      return this;
    }

    public void unsetNewNamespaceName() {
      this.newNamespaceName = null;
    }

    /** Returns true if field newNamespaceName is set (has been assigned a value) and false otherwise */
    public boolean isSetNewNamespaceName() {
      return this.newNamespaceName != null;
    }

    public void setNewNamespaceNameIsSet(boolean value) {
      if (!value) {
        this.newNamespaceName = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case LOGIN:
        if (value == null) {
          unsetLogin();
        } else {
          if (value instanceof byte[]) {
            setLogin((byte[])value);
          } else {
            setLogin((java.nio.ByteBuffer)value);
          }
        }
        break;

      case OLD_NAMESPACE_NAME:
        if (value == null) {
          unsetOldNamespaceName();
        } else {
          setOldNamespaceName((java.lang.String)value);
        }
        break;

      case NEW_NAMESPACE_NAME:
        if (value == null) {
          unsetNewNamespaceName();
        } else {
          setNewNamespaceName((java.lang.String)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case LOGIN:
        return getLogin();

      case OLD_NAMESPACE_NAME:
        return getOldNamespaceName();

      case NEW_NAMESPACE_NAME:
        return getNewNamespaceName();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case LOGIN:
        return isSetLogin();
      case OLD_NAMESPACE_NAME:
        return isSetOldNamespaceName();
      case NEW_NAMESPACE_NAME:
        return isSetNewNamespaceName();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof renameNamespace_args)
        return this.equals((renameNamespace_args)that);
      return false;
    }

    public boolean equals(renameNamespace_args that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_login = true && this.isSetLogin();
      boolean that_present_login = true && that.isSetLogin();
      if (this_present_login || that_present_login) {
        if (!(this_present_login && that_present_login))
          return false;
        if (!this.login.equals(that.login))
          return false;
      }

      boolean this_present_oldNamespaceName = true && this.isSetOldNamespaceName();
      boolean that_present_oldNamespaceName = true && that.isSetOldNamespaceName();
      if (this_present_oldNamespaceName || that_present_oldNamespaceName) {
        if (!(this_present_oldNamespaceName && that_present_oldNamespaceName))
          return false;
        if (!this.oldNamespaceName.equals(that.oldNamespaceName))
          return false;
      }

      boolean this_present_newNamespaceName = true && this.isSetNewNamespaceName();
      boolean that_present_newNamespaceName = true && that.isSetNewNamespaceName();
      if (this_present_newNamespaceName || that_present_newNamespaceName) {
        if (!(this_present_newNamespaceName && that_present_newNamespaceName))
          return false;
        if (!this.newNamespaceName.equals(that.newNamespaceName))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
      if (isSetLogin())
        hashCode = hashCode * 8191 + login.hashCode();

      hashCode = hashCode * 8191 + ((isSetOldNamespaceName()) ? 131071 : 524287);
      if (isSetOldNamespaceName())
        hashCode = hashCode * 8191 + oldNamespaceName.hashCode();

      hashCode = hashCode * 8191 + ((isSetNewNamespaceName()) ? 131071 : 524287);
      if (isSetNewNamespaceName())
        hashCode = hashCode * 8191 + newNamespaceName.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(renameNamespace_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLogin()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOldNamespaceName()).compareTo(other.isSetOldNamespaceName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOldNamespaceName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.oldNamespaceName, other.oldNamespaceName);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetNewNamespaceName()).compareTo(other.isSetNewNamespaceName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetNewNamespaceName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.newNamespaceName, other.newNamespaceName);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("renameNamespace_args(");
      boolean first = true;

      sb.append("login:");
      if (this.login == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.login, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("oldNamespaceName:");
      if (this.oldNamespaceName == null) {
        sb.append("null");
      } else {
        sb.append(this.oldNamespaceName);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("newNamespaceName:");
      if (this.newNamespaceName == null) {
        sb.append("null");
      } else {
        sb.append(this.newNamespaceName);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class renameNamespace_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public renameNamespace_argsStandardScheme getScheme() {
        return new renameNamespace_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // LOGIN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.login = iprot.readBinary();
                struct.setLoginIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OLD_NAMESPACE_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.oldNamespaceName = iprot.readString();
                struct.setOldNamespaceNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // NEW_NAMESPACE_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.newNamespaceName = iprot.readString();
                struct.setNewNamespaceNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, renameNamespace_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.login != null) {
          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
          oprot.writeBinary(struct.login);
          oprot.writeFieldEnd();
        }
        if (struct.oldNamespaceName != null) {
          oprot.writeFieldBegin(OLD_NAMESPACE_NAME_FIELD_DESC);
          oprot.writeString(struct.oldNamespaceName);
          oprot.writeFieldEnd();
        }
        if (struct.newNamespaceName != null) {
          oprot.writeFieldBegin(NEW_NAMESPACE_NAME_FIELD_DESC);
          oprot.writeString(struct.newNamespaceName);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class renameNamespace_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public renameNamespace_argsTupleScheme getScheme() {
        return new renameNamespace_argsTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetOldNamespaceName()) {
          optionals.set(1);
        }
        if (struct.isSetNewNamespaceName()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetLogin()) {
          oprot.writeBinary(struct.login);
        }
        if (struct.isSetOldNamespaceName()) {
          oprot.writeString(struct.oldNamespaceName);
        }
        if (struct.isSetNewNamespaceName()) {
          oprot.writeString(struct.newNamespaceName);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, renameNamespace_args struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.oldNamespaceName = iprot.readString();
          struct.setOldNamespaceNameIsSet(true);
        }
        if (incoming.get(2)) {
          struct.newNamespaceName = iprot.readString();
          struct.setNewNamespaceNameIsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("renameNamespace_result");

    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField OUCH3_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch3", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    private static final org.apache.thrift.protocol.TField OUCH4_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch4", org.apache.thrift.protocol.TType.STRUCT, (short)4);

    private static final 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
    public NamespaceNotFoundException ouch3; // required
    public NamespaceExistsException ouch4; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      OUCH1((short)1, "ouch1"),
      OUCH2((short)2, "ouch2"),
      OUCH3((short)3, "ouch3"),
      OUCH4((short)4, "ouch4");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // OUCH1
            return OUCH1;
          case 2: // OUCH2
            return OUCH2;
          case 3: // OUCH3
            return OUCH3;
          case 4: // OUCH4
            return OUCH4;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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.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.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.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);
    }

    public renameNamespace_result() {
    }

    public renameNamespace_result(
      AccumuloException ouch1,
      AccumuloSecurityException ouch2,
      NamespaceNotFoundException ouch3,
      NamespaceExistsException ouch4)
    {
      this();
      this.ouch1 = ouch1;
      this.ouch2 = ouch2;
      this.ouch3 = ouch3;
      this.ouch4 = ouch4;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public renameNamespace_result(renameNamespace_result other) {
      if (other.isSetOuch1()) {
        this.ouch1 = new AccumuloException(other.ouch1);
      }
      if (other.isSetOuch2()) {
        this.ouch2 = new AccumuloSecurityException(other.ouch2);
      }
      if (other.isSetOuch3()) {
        this.ouch3 = new NamespaceNotFoundException(other.ouch3);
      }
      if (other.isSetOuch4()) {
        this.ouch4 = new NamespaceExistsException(other.ouch4);
      }
    }

    public renameNamespace_result deepCopy() {
      return new renameNamespace_result(this);
    }

    @Override
    public void clear() {
      this.ouch1 = null;
      this.ouch2 = null;
      this.ouch3 = null;
      this.ouch4 = null;
    }

    public AccumuloException getOuch1() {
      return this.ouch1;
    }

    public renameNamespace_result setOuch1(AccumuloException ouch1) {
      this.ouch1 = ouch1;
      return this;
    }

    public void unsetOuch1() {
      this.ouch1 = null;
    }

    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch1() {
      return this.ouch1 != null;
    }

    public void setOuch1IsSet(boolean value) {
      if (!value) {
        this.ouch1 = null;
      }
    }

    public AccumuloSecurityException getOuch2() {
      return this.ouch2;
    }

    public renameNamespace_result setOuch2(AccumuloSecurityException ouch2) {
      this.ouch2 = ouch2;
      return this;
    }

    public void unsetOuch2() {
      this.ouch2 = null;
    }

    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch2() {
      return this.ouch2 != null;
    }

    public void setOuch2IsSet(boolean value) {
      if (!value) {
        this.ouch2 = null;
      }
    }

    public NamespaceNotFoundException getOuch3() {
      return this.ouch3;
    }

    public renameNamespace_result setOuch3(NamespaceNotFoundException ouch3) {
      this.ouch3 = ouch3;
      return this;
    }

    public void unsetOuch3() {
      this.ouch3 = null;
    }

    /** Returns true if field ouch3 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch3() {
      return this.ouch3 != null;
    }

    public void setOuch3IsSet(boolean value) {
      if (!value) {
        this.ouch3 = null;
      }
    }

    public NamespaceExistsException getOuch4() {
      return this.ouch4;
    }

    public renameNamespace_result setOuch4(NamespaceExistsException ouch4) {
      this.ouch4 = ouch4;
      return this;
    }

    public void unsetOuch4() {
      this.ouch4 = null;
    }

    /** Returns true if field ouch4 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch4() {
      return this.ouch4 != null;
    }

    public void setOuch4IsSet(boolean value) {
      if (!value) {
        this.ouch4 = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case OUCH1:
        if (value == null) {
          unsetOuch1();
        } else {
          setOuch1((AccumuloException)value);
        }
        break;

      case OUCH2:
        if (value == null) {
          unsetOuch2();
        } else {
          setOuch2((AccumuloSecurityException)value);
        }
        break;

      case OUCH3:
        if (value == null) {
          unsetOuch3();
        } else {
          setOuch3((NamespaceNotFoundException)value);
        }
        break;

      case OUCH4:
        if (value == null) {
          unsetOuch4();
        } else {
          setOuch4((NamespaceExistsException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case OUCH1:
        return getOuch1();

      case OUCH2:
        return getOuch2();

      case OUCH3:
        return getOuch3();

      case OUCH4:
        return getOuch4();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case OUCH1:
        return isSetOuch1();
      case OUCH2:
        return isSetOuch2();
      case OUCH3:
        return isSetOuch3();
      case OUCH4:
        return isSetOuch4();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof renameNamespace_result)
        return this.equals((renameNamespace_result)that);
      return false;
    }

    public boolean equals(renameNamespace_result that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_ouch1 = true && this.isSetOuch1();
      boolean that_present_ouch1 = true && that.isSetOuch1();
      if (this_present_ouch1 || that_present_ouch1) {
        if (!(this_present_ouch1 && that_present_ouch1))
          return false;
        if (!this.ouch1.equals(that.ouch1))
          return false;
      }

      boolean this_present_ouch2 = true && this.isSetOuch2();
      boolean that_present_ouch2 = true && that.isSetOuch2();
      if (this_present_ouch2 || that_present_ouch2) {
        if (!(this_present_ouch2 && that_present_ouch2))
          return false;
        if (!this.ouch2.equals(that.ouch2))
          return false;
      }

      boolean this_present_ouch3 = true && this.isSetOuch3();
      boolean that_present_ouch3 = true && that.isSetOuch3();
      if (this_present_ouch3 || that_present_ouch3) {
        if (!(this_present_ouch3 && that_present_ouch3))
          return false;
        if (!this.ouch3.equals(that.ouch3))
          return false;
      }

      boolean this_present_ouch4 = true && this.isSetOuch4();
      boolean that_present_ouch4 = true && that.isSetOuch4();
      if (this_present_ouch4 || that_present_ouch4) {
        if (!(this_present_ouch4 && that_present_ouch4))
          return false;
        if (!this.ouch4.equals(that.ouch4))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
      if (isSetOuch1())
        hashCode = hashCode * 8191 + ouch1.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
      if (isSetOuch2())
        hashCode = hashCode * 8191 + ouch2.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
      if (isSetOuch3())
        hashCode = hashCode * 8191 + ouch3.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch4()) ? 131071 : 524287);
      if (isSetOuch4())
        hashCode = hashCode * 8191 + ouch4.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(renameNamespace_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch1()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch2()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch3()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch3, other.ouch3);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch4()).compareTo(other.isSetOuch4());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch4()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch4, other.ouch4);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("renameNamespace_result(");
      boolean first = true;

      sb.append("ouch1:");
      if (this.ouch1 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch1);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch2:");
      if (this.ouch2 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch2);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch3:");
      if (this.ouch3 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch3);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch4:");
      if (this.ouch4 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch4);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class renameNamespace_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public renameNamespace_resultStandardScheme getScheme() {
        return new renameNamespace_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // OUCH1
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch1 = new AccumuloException();
                struct.ouch1.read(iprot);
                struct.setOuch1IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OUCH2
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch2 = new AccumuloSecurityException();
                struct.ouch2.read(iprot);
                struct.setOuch2IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // OUCH3
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch3 = new NamespaceNotFoundException();
                struct.ouch3.read(iprot);
                struct.setOuch3IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // OUCH4
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch4 = new NamespaceExistsException();
                struct.ouch4.read(iprot);
                struct.setOuch4IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, renameNamespace_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.ouch1 != null) {
          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
          struct.ouch1.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch2 != null) {
          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
          struct.ouch2.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch3 != null) {
          oprot.writeFieldBegin(OUCH3_FIELD_DESC);
          struct.ouch3.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch4 != null) {
          oprot.writeFieldBegin(OUCH4_FIELD_DESC);
          struct.ouch4.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class renameNamespace_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public renameNamespace_resultTupleScheme getScheme() {
        return new renameNamespace_resultTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetOuch2()) {
          optionals.set(1);
        }
        if (struct.isSetOuch3()) {
          optionals.set(2);
        }
        if (struct.isSetOuch4()) {
          optionals.set(3);
        }
        oprot.writeBitSet(optionals, 4);
        if (struct.isSetOuch1()) {
          struct.ouch1.write(oprot);
        }
        if (struct.isSetOuch2()) {
          struct.ouch2.write(oprot);
        }
        if (struct.isSetOuch3()) {
          struct.ouch3.write(oprot);
        }
        if (struct.isSetOuch4()) {
          struct.ouch4.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, renameNamespace_result struct) throws org.apache.thrift.TException {
        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);
          struct.setOuch1IsSet(true);
        }
        if (incoming.get(1)) {
          struct.ouch2 = new AccumuloSecurityException();
          struct.ouch2.read(iprot);
          struct.setOuch2IsSet(true);
        }
        if (incoming.get(2)) {
          struct.ouch3 = new NamespaceNotFoundException();
          struct.ouch3.read(iprot);
          struct.setOuch3IsSet(true);
        }
        if (incoming.get(3)) {
          struct.ouch4 = new NamespaceExistsException();
          struct.ouch4.read(iprot);
          struct.setOuch4IsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("setNamespaceProperty_args");

    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField NAMESPACE_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("namespaceName", org.apache.thrift.protocol.TType.STRING, (short)2);
    private static final org.apache.thrift.protocol.TField PROPERTY_FIELD_DESC = new org.apache.thrift.protocol.TField("property", org.apache.thrift.protocol.TType.STRING, (short)3);
    private static final org.apache.thrift.protocol.TField VALUE_FIELD_DESC = new org.apache.thrift.protocol.TField("value", org.apache.thrift.protocol.TType.STRING, (short)4);

    private static final 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 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 {
      LOGIN((short)1, "login"),
      NAMESPACE_NAME((short)2, "namespaceName"),
      PROPERTY((short)3, "property"),
      VALUE((short)4, "value");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // LOGIN
            return LOGIN;
          case 2: // NAMESPACE_NAME
            return NAMESPACE_NAME;
          case 3: // PROPERTY
            return PROPERTY;
          case 4: // VALUE
            return VALUE;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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)));
      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 = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(setNamespaceProperty_args.class, metaDataMap);
    }

    public setNamespaceProperty_args() {
    }

    public setNamespaceProperty_args(
      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);
      this.namespaceName = namespaceName;
      this.property = property;
      this.value = value;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public setNamespaceProperty_args(setNamespaceProperty_args other) {
      if (other.isSetLogin()) {
        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
      }
      if (other.isSetNamespaceName()) {
        this.namespaceName = other.namespaceName;
      }
      if (other.isSetProperty()) {
        this.property = other.property;
      }
      if (other.isSetValue()) {
        this.value = other.value;
      }
    }

    public setNamespaceProperty_args deepCopy() {
      return new setNamespaceProperty_args(this);
    }

    @Override
    public void clear() {
      this.login = null;
      this.namespaceName = null;
      this.property = null;
      this.value = null;
    }

    public byte[] getLogin() {
      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
      return login == null ? null : login.array();
    }

    public java.nio.ByteBuffer bufferForLogin() {
      return org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    public setNamespaceProperty_args setLogin(byte[] login) {
      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
      return this;
    }

    public setNamespaceProperty_args setLogin(java.nio.ByteBuffer login) {
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      return this;
    }

    public void unsetLogin() {
      this.login = null;
    }

    /** Returns true if field login is set (has been assigned a value) and false otherwise */
    public boolean isSetLogin() {
      return this.login != null;
    }

    public void setLoginIsSet(boolean value) {
      if (!value) {
        this.login = null;
      }
    }

    public java.lang.String getNamespaceName() {
      return this.namespaceName;
    }

    public setNamespaceProperty_args setNamespaceName(java.lang.String namespaceName) {
      this.namespaceName = namespaceName;
      return this;
    }

    public void unsetNamespaceName() {
      this.namespaceName = null;
    }

    /** Returns true if field namespaceName is set (has been assigned a value) and false otherwise */
    public boolean isSetNamespaceName() {
      return this.namespaceName != null;
    }

    public void setNamespaceNameIsSet(boolean value) {
      if (!value) {
        this.namespaceName = null;
      }
    }

    public java.lang.String getProperty() {
      return this.property;
    }

    public setNamespaceProperty_args setProperty(java.lang.String property) {
      this.property = property;
      return this;
    }

    public void unsetProperty() {
      this.property = null;
    }

    /** Returns true if field property is set (has been assigned a value) and false otherwise */
    public boolean isSetProperty() {
      return this.property != null;
    }

    public void setPropertyIsSet(boolean value) {
      if (!value) {
        this.property = null;
      }
    }

    public java.lang.String getValue() {
      return this.value;
    }

    public setNamespaceProperty_args setValue(java.lang.String value) {
      this.value = value;
      return this;
    }

    public void unsetValue() {
      this.value = null;
    }

    /** Returns true if field value is set (has been assigned a value) and false otherwise */
    public boolean isSetValue() {
      return this.value != null;
    }

    public void setValueIsSet(boolean value) {
      if (!value) {
        this.value = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case LOGIN:
        if (value == null) {
          unsetLogin();
        } else {
          if (value instanceof byte[]) {
            setLogin((byte[])value);
          } else {
            setLogin((java.nio.ByteBuffer)value);
          }
        }
        break;

      case NAMESPACE_NAME:
        if (value == null) {
          unsetNamespaceName();
        } else {
          setNamespaceName((java.lang.String)value);
        }
        break;

      case PROPERTY:
        if (value == null) {
          unsetProperty();
        } else {
          setProperty((java.lang.String)value);
        }
        break;

      case VALUE:
        if (value == null) {
          unsetValue();
        } else {
          setValue((java.lang.String)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case LOGIN:
        return getLogin();

      case NAMESPACE_NAME:
        return getNamespaceName();

      case PROPERTY:
        return getProperty();

      case VALUE:
        return getValue();

      }
      throw new 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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case LOGIN:
        return isSetLogin();
      case NAMESPACE_NAME:
        return isSetNamespaceName();
      case PROPERTY:
        return isSetProperty();
      case VALUE:
        return isSetValue();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof setNamespaceProperty_args)
        return this.equals((setNamespaceProperty_args)that);
      return false;
    }

    public boolean equals(setNamespaceProperty_args that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_login = true && this.isSetLogin();
      boolean that_present_login = true && that.isSetLogin();
      if (this_present_login || that_present_login) {
        if (!(this_present_login && that_present_login))
          return false;
        if (!this.login.equals(that.login))
          return false;
      }

      boolean this_present_namespaceName = true && this.isSetNamespaceName();
      boolean that_present_namespaceName = true && that.isSetNamespaceName();
      if (this_present_namespaceName || that_present_namespaceName) {
        if (!(this_present_namespaceName && that_present_namespaceName))
          return false;
        if (!this.namespaceName.equals(that.namespaceName))
          return false;
      }

      boolean this_present_property = true && this.isSetProperty();
      boolean that_present_property = true && that.isSetProperty();
      if (this_present_property || that_present_property) {
        if (!(this_present_property && that_present_property))
          return false;
        if (!this.property.equals(that.property))
          return false;
      }

      boolean this_present_value = true && this.isSetValue();
      boolean that_present_value = true && that.isSetValue();
      if (this_present_value || that_present_value) {
        if (!(this_present_value && that_present_value))
          return false;
        if (!this.value.equals(that.value))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
      if (isSetLogin())
        hashCode = hashCode * 8191 + login.hashCode();

      hashCode = hashCode * 8191 + ((isSetNamespaceName()) ? 131071 : 524287);
      if (isSetNamespaceName())
        hashCode = hashCode * 8191 + namespaceName.hashCode();

      hashCode = hashCode * 8191 + ((isSetProperty()) ? 131071 : 524287);
      if (isSetProperty())
        hashCode = hashCode * 8191 + property.hashCode();

      hashCode = hashCode * 8191 + ((isSetValue()) ? 131071 : 524287);
      if (isSetValue())
        hashCode = hashCode * 8191 + value.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(setNamespaceProperty_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLogin()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetNamespaceName()).compareTo(other.isSetNamespaceName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetNamespaceName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.namespaceName, other.namespaceName);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetProperty()).compareTo(other.isSetProperty());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetProperty()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.property, other.property);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetValue()).compareTo(other.isSetValue());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetValue()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.value, other.value);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("setNamespaceProperty_args(");
      boolean first = true;

      sb.append("login:");
      if (this.login == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.login, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("namespaceName:");
      if (this.namespaceName == null) {
        sb.append("null");
      } else {
        sb.append(this.namespaceName);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("property:");
      if (this.property == null) {
        sb.append("null");
      } else {
        sb.append(this.property);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("value:");
      if (this.value == null) {
        sb.append("null");
      } else {
        sb.append(this.value);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class setNamespaceProperty_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public setNamespaceProperty_argsStandardScheme getScheme() {
        return new setNamespaceProperty_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // LOGIN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.login = iprot.readBinary();
                struct.setLoginIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // NAMESPACE_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.namespaceName = iprot.readString();
                struct.setNamespaceNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // PROPERTY
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.property = iprot.readString();
                struct.setPropertyIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // VALUE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.value = iprot.readString();
                struct.setValueIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, setNamespaceProperty_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.login != null) {
          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
          oprot.writeBinary(struct.login);
          oprot.writeFieldEnd();
        }
        if (struct.namespaceName != null) {
          oprot.writeFieldBegin(NAMESPACE_NAME_FIELD_DESC);
          oprot.writeString(struct.namespaceName);
          oprot.writeFieldEnd();
        }
        if (struct.property != null) {
          oprot.writeFieldBegin(PROPERTY_FIELD_DESC);
          oprot.writeString(struct.property);
          oprot.writeFieldEnd();
        }
        if (struct.value != null) {
          oprot.writeFieldBegin(VALUE_FIELD_DESC);
          oprot.writeString(struct.value);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class setNamespaceProperty_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public setNamespaceProperty_argsTupleScheme getScheme() {
        return new setNamespaceProperty_argsTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetNamespaceName()) {
          optionals.set(1);
        }
        if (struct.isSetProperty()) {
          optionals.set(2);
        }
        if (struct.isSetValue()) {
          optionals.set(3);
        }
        oprot.writeBitSet(optionals, 4);
        if (struct.isSetLogin()) {
          oprot.writeBinary(struct.login);
        }
        if (struct.isSetNamespaceName()) {
          oprot.writeString(struct.namespaceName);
        }
        if (struct.isSetProperty()) {
          oprot.writeString(struct.property);
        }
        if (struct.isSetValue()) {
          oprot.writeString(struct.value);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, setNamespaceProperty_args struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.namespaceName = iprot.readString();
          struct.setNamespaceNameIsSet(true);
        }
        if (incoming.get(2)) {
          struct.property = iprot.readString();
          struct.setPropertyIsSet(true);
        }
        if (incoming.get(3)) {
          struct.value = iprot.readString();
          struct.setValueIsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("setNamespaceProperty_result");

    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField OUCH3_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch3", org.apache.thrift.protocol.TType.STRUCT, (short)3);

    private static final 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
    public NamespaceNotFoundException ouch3; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      OUCH1((short)1, "ouch1"),
      OUCH2((short)2, "ouch2"),
      OUCH3((short)3, "ouch3");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // OUCH1
            return OUCH1;
          case 2: // OUCH2
            return OUCH2;
          case 3: // OUCH3
            return OUCH3;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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.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.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);
    }

    public setNamespaceProperty_result() {
    }

    public setNamespaceProperty_result(
      AccumuloException ouch1,
      AccumuloSecurityException ouch2,
      NamespaceNotFoundException ouch3)
    {
      this();
      this.ouch1 = ouch1;
      this.ouch2 = ouch2;
      this.ouch3 = ouch3;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public setNamespaceProperty_result(setNamespaceProperty_result other) {
      if (other.isSetOuch1()) {
        this.ouch1 = new AccumuloException(other.ouch1);
      }
      if (other.isSetOuch2()) {
        this.ouch2 = new AccumuloSecurityException(other.ouch2);
      }
      if (other.isSetOuch3()) {
        this.ouch3 = new NamespaceNotFoundException(other.ouch3);
      }
    }

    public setNamespaceProperty_result deepCopy() {
      return new setNamespaceProperty_result(this);
    }

    @Override
    public void clear() {
      this.ouch1 = null;
      this.ouch2 = null;
      this.ouch3 = null;
    }

    public AccumuloException getOuch1() {
      return this.ouch1;
    }

    public setNamespaceProperty_result setOuch1(AccumuloException ouch1) {
      this.ouch1 = ouch1;
      return this;
    }

    public void unsetOuch1() {
      this.ouch1 = null;
    }

    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch1() {
      return this.ouch1 != null;
    }

    public void setOuch1IsSet(boolean value) {
      if (!value) {
        this.ouch1 = null;
      }
    }

    public AccumuloSecurityException getOuch2() {
      return this.ouch2;
    }

    public setNamespaceProperty_result setOuch2(AccumuloSecurityException ouch2) {
      this.ouch2 = ouch2;
      return this;
    }

    public void unsetOuch2() {
      this.ouch2 = null;
    }

    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch2() {
      return this.ouch2 != null;
    }

    public void setOuch2IsSet(boolean value) {
      if (!value) {
        this.ouch2 = null;
      }
    }

    public NamespaceNotFoundException getOuch3() {
      return this.ouch3;
    }

    public setNamespaceProperty_result setOuch3(NamespaceNotFoundException ouch3) {
      this.ouch3 = ouch3;
      return this;
    }

    public void unsetOuch3() {
      this.ouch3 = null;
    }

    /** Returns true if field ouch3 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch3() {
      return this.ouch3 != null;
    }

    public void setOuch3IsSet(boolean value) {
      if (!value) {
        this.ouch3 = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case OUCH1:
        if (value == null) {
          unsetOuch1();
        } else {
          setOuch1((AccumuloException)value);
        }
        break;

      case OUCH2:
        if (value == null) {
          unsetOuch2();
        } else {
          setOuch2((AccumuloSecurityException)value);
        }
        break;

      case OUCH3:
        if (value == null) {
          unsetOuch3();
        } else {
          setOuch3((NamespaceNotFoundException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case OUCH1:
        return getOuch1();

      case OUCH2:
        return getOuch2();

      case OUCH3:
        return getOuch3();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case OUCH1:
        return isSetOuch1();
      case OUCH2:
        return isSetOuch2();
      case OUCH3:
        return isSetOuch3();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof setNamespaceProperty_result)
        return this.equals((setNamespaceProperty_result)that);
      return false;
    }

    public boolean equals(setNamespaceProperty_result that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_ouch1 = true && this.isSetOuch1();
      boolean that_present_ouch1 = true && that.isSetOuch1();
      if (this_present_ouch1 || that_present_ouch1) {
        if (!(this_present_ouch1 && that_present_ouch1))
          return false;
        if (!this.ouch1.equals(that.ouch1))
          return false;
      }

      boolean this_present_ouch2 = true && this.isSetOuch2();
      boolean that_present_ouch2 = true && that.isSetOuch2();
      if (this_present_ouch2 || that_present_ouch2) {
        if (!(this_present_ouch2 && that_present_ouch2))
          return false;
        if (!this.ouch2.equals(that.ouch2))
          return false;
      }

      boolean this_present_ouch3 = true && this.isSetOuch3();
      boolean that_present_ouch3 = true && that.isSetOuch3();
      if (this_present_ouch3 || that_present_ouch3) {
        if (!(this_present_ouch3 && that_present_ouch3))
          return false;
        if (!this.ouch3.equals(that.ouch3))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
      if (isSetOuch1())
        hashCode = hashCode * 8191 + ouch1.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
      if (isSetOuch2())
        hashCode = hashCode * 8191 + ouch2.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
      if (isSetOuch3())
        hashCode = hashCode * 8191 + ouch3.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(setNamespaceProperty_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch1()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch2()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch3()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch3, other.ouch3);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("setNamespaceProperty_result(");
      boolean first = true;

      sb.append("ouch1:");
      if (this.ouch1 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch1);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch2:");
      if (this.ouch2 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch2);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch3:");
      if (this.ouch3 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch3);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class setNamespaceProperty_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public setNamespaceProperty_resultStandardScheme getScheme() {
        return new setNamespaceProperty_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // OUCH1
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch1 = new AccumuloException();
                struct.ouch1.read(iprot);
                struct.setOuch1IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OUCH2
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch2 = new AccumuloSecurityException();
                struct.ouch2.read(iprot);
                struct.setOuch2IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // OUCH3
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch3 = new NamespaceNotFoundException();
                struct.ouch3.read(iprot);
                struct.setOuch3IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, setNamespaceProperty_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.ouch1 != null) {
          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
          struct.ouch1.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch2 != null) {
          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
          struct.ouch2.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch3 != null) {
          oprot.writeFieldBegin(OUCH3_FIELD_DESC);
          struct.ouch3.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class setNamespaceProperty_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public setNamespaceProperty_resultTupleScheme getScheme() {
        return new setNamespaceProperty_resultTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetOuch2()) {
          optionals.set(1);
        }
        if (struct.isSetOuch3()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetOuch1()) {
          struct.ouch1.write(oprot);
        }
        if (struct.isSetOuch2()) {
          struct.ouch2.write(oprot);
        }
        if (struct.isSetOuch3()) {
          struct.ouch3.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, setNamespaceProperty_result struct) throws org.apache.thrift.TException {
        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);
          struct.setOuch1IsSet(true);
        }
        if (incoming.get(1)) {
          struct.ouch2 = new AccumuloSecurityException();
          struct.ouch2.read(iprot);
          struct.setOuch2IsSet(true);
        }
        if (incoming.get(2)) {
          struct.ouch3 = new NamespaceNotFoundException();
          struct.ouch3.read(iprot);
          struct.setOuch3IsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("removeNamespaceProperty_args");

    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField NAMESPACE_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("namespaceName", org.apache.thrift.protocol.TType.STRING, (short)2);
    private static final org.apache.thrift.protocol.TField PROPERTY_FIELD_DESC = new org.apache.thrift.protocol.TField("property", org.apache.thrift.protocol.TType.STRING, (short)3);

    private static final 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 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 {
      LOGIN((short)1, "login"),
      NAMESPACE_NAME((short)2, "namespaceName"),
      PROPERTY((short)3, "property");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // LOGIN
            return LOGIN;
          case 2: // NAMESPACE_NAME
            return NAMESPACE_NAME;
          case 3: // PROPERTY
            return PROPERTY;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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 = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(removeNamespaceProperty_args.class, metaDataMap);
    }

    public removeNamespaceProperty_args() {
    }

    public removeNamespaceProperty_args(
      java.nio.ByteBuffer login,
      java.lang.String namespaceName,
      java.lang.String property)
    {
      this();
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      this.namespaceName = namespaceName;
      this.property = property;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public removeNamespaceProperty_args(removeNamespaceProperty_args other) {
      if (other.isSetLogin()) {
        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
      }
      if (other.isSetNamespaceName()) {
        this.namespaceName = other.namespaceName;
      }
      if (other.isSetProperty()) {
        this.property = other.property;
      }
    }

    public removeNamespaceProperty_args deepCopy() {
      return new removeNamespaceProperty_args(this);
    }

    @Override
    public void clear() {
      this.login = null;
      this.namespaceName = null;
      this.property = null;
    }

    public byte[] getLogin() {
      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
      return login == null ? null : login.array();
    }

    public java.nio.ByteBuffer bufferForLogin() {
      return org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    public removeNamespaceProperty_args setLogin(byte[] login) {
      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
      return this;
    }

    public removeNamespaceProperty_args setLogin(java.nio.ByteBuffer login) {
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      return this;
    }

    public void unsetLogin() {
      this.login = null;
    }

    /** Returns true if field login is set (has been assigned a value) and false otherwise */
    public boolean isSetLogin() {
      return this.login != null;
    }

    public void setLoginIsSet(boolean value) {
      if (!value) {
        this.login = null;
      }
    }

    public java.lang.String getNamespaceName() {
      return this.namespaceName;
    }

    public removeNamespaceProperty_args setNamespaceName(java.lang.String namespaceName) {
      this.namespaceName = namespaceName;
      return this;
    }

    public void unsetNamespaceName() {
      this.namespaceName = null;
    }

    /** Returns true if field namespaceName is set (has been assigned a value) and false otherwise */
    public boolean isSetNamespaceName() {
      return this.namespaceName != null;
    }

    public void setNamespaceNameIsSet(boolean value) {
      if (!value) {
        this.namespaceName = null;
      }
    }

    public java.lang.String getProperty() {
      return this.property;
    }

    public removeNamespaceProperty_args setProperty(java.lang.String property) {
      this.property = property;
      return this;
    }

    public void unsetProperty() {
      this.property = null;
    }

    /** Returns true if field property is set (has been assigned a value) and false otherwise */
    public boolean isSetProperty() {
      return this.property != null;
    }

    public void setPropertyIsSet(boolean value) {
      if (!value) {
        this.property = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case LOGIN:
        if (value == null) {
          unsetLogin();
        } else {
          if (value instanceof byte[]) {
            setLogin((byte[])value);
          } else {
            setLogin((java.nio.ByteBuffer)value);
          }
        }
        break;

      case NAMESPACE_NAME:
        if (value == null) {
          unsetNamespaceName();
        } else {
          setNamespaceName((java.lang.String)value);
        }
        break;

      case PROPERTY:
        if (value == null) {
          unsetProperty();
        } else {
          setProperty((java.lang.String)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case LOGIN:
        return getLogin();

      case NAMESPACE_NAME:
        return getNamespaceName();

      case PROPERTY:
        return getProperty();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case LOGIN:
        return isSetLogin();
      case NAMESPACE_NAME:
        return isSetNamespaceName();
      case PROPERTY:
        return isSetProperty();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof removeNamespaceProperty_args)
        return this.equals((removeNamespaceProperty_args)that);
      return false;
    }

    public boolean equals(removeNamespaceProperty_args that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_login = true && this.isSetLogin();
      boolean that_present_login = true && that.isSetLogin();
      if (this_present_login || that_present_login) {
        if (!(this_present_login && that_present_login))
          return false;
        if (!this.login.equals(that.login))
          return false;
      }

      boolean this_present_namespaceName = true && this.isSetNamespaceName();
      boolean that_present_namespaceName = true && that.isSetNamespaceName();
      if (this_present_namespaceName || that_present_namespaceName) {
        if (!(this_present_namespaceName && that_present_namespaceName))
          return false;
        if (!this.namespaceName.equals(that.namespaceName))
          return false;
      }

      boolean this_present_property = true && this.isSetProperty();
      boolean that_present_property = true && that.isSetProperty();
      if (this_present_property || that_present_property) {
        if (!(this_present_property && that_present_property))
          return false;
        if (!this.property.equals(that.property))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
      if (isSetLogin())
        hashCode = hashCode * 8191 + login.hashCode();

      hashCode = hashCode * 8191 + ((isSetNamespaceName()) ? 131071 : 524287);
      if (isSetNamespaceName())
        hashCode = hashCode * 8191 + namespaceName.hashCode();

      hashCode = hashCode * 8191 + ((isSetProperty()) ? 131071 : 524287);
      if (isSetProperty())
        hashCode = hashCode * 8191 + property.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(removeNamespaceProperty_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLogin()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetNamespaceName()).compareTo(other.isSetNamespaceName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetNamespaceName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.namespaceName, other.namespaceName);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetProperty()).compareTo(other.isSetProperty());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetProperty()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.property, other.property);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("removeNamespaceProperty_args(");
      boolean first = true;

      sb.append("login:");
      if (this.login == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.login, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("namespaceName:");
      if (this.namespaceName == null) {
        sb.append("null");
      } else {
        sb.append(this.namespaceName);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("property:");
      if (this.property == null) {
        sb.append("null");
      } else {
        sb.append(this.property);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class removeNamespaceProperty_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public removeNamespaceProperty_argsStandardScheme getScheme() {
        return new removeNamespaceProperty_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // LOGIN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.login = iprot.readBinary();
                struct.setLoginIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // NAMESPACE_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.namespaceName = iprot.readString();
                struct.setNamespaceNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // PROPERTY
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.property = iprot.readString();
                struct.setPropertyIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, removeNamespaceProperty_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.login != null) {
          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
          oprot.writeBinary(struct.login);
          oprot.writeFieldEnd();
        }
        if (struct.namespaceName != null) {
          oprot.writeFieldBegin(NAMESPACE_NAME_FIELD_DESC);
          oprot.writeString(struct.namespaceName);
          oprot.writeFieldEnd();
        }
        if (struct.property != null) {
          oprot.writeFieldBegin(PROPERTY_FIELD_DESC);
          oprot.writeString(struct.property);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class removeNamespaceProperty_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public removeNamespaceProperty_argsTupleScheme getScheme() {
        return new removeNamespaceProperty_argsTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetNamespaceName()) {
          optionals.set(1);
        }
        if (struct.isSetProperty()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetLogin()) {
          oprot.writeBinary(struct.login);
        }
        if (struct.isSetNamespaceName()) {
          oprot.writeString(struct.namespaceName);
        }
        if (struct.isSetProperty()) {
          oprot.writeString(struct.property);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, removeNamespaceProperty_args struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.namespaceName = iprot.readString();
          struct.setNamespaceNameIsSet(true);
        }
        if (incoming.get(2)) {
          struct.property = iprot.readString();
          struct.setPropertyIsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("removeNamespaceProperty_result");

    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField OUCH3_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch3", org.apache.thrift.protocol.TType.STRUCT, (short)3);

    private static final 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
    public NamespaceNotFoundException ouch3; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      OUCH1((short)1, "ouch1"),
      OUCH2((short)2, "ouch2"),
      OUCH3((short)3, "ouch3");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // OUCH1
            return OUCH1;
          case 2: // OUCH2
            return OUCH2;
          case 3: // OUCH3
            return OUCH3;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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.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.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);
    }

    public removeNamespaceProperty_result() {
    }

    public removeNamespaceProperty_result(
      AccumuloException ouch1,
      AccumuloSecurityException ouch2,
      NamespaceNotFoundException ouch3)
    {
      this();
      this.ouch1 = ouch1;
      this.ouch2 = ouch2;
      this.ouch3 = ouch3;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public removeNamespaceProperty_result(removeNamespaceProperty_result other) {
      if (other.isSetOuch1()) {
        this.ouch1 = new AccumuloException(other.ouch1);
      }
      if (other.isSetOuch2()) {
        this.ouch2 = new AccumuloSecurityException(other.ouch2);
      }
      if (other.isSetOuch3()) {
        this.ouch3 = new NamespaceNotFoundException(other.ouch3);
      }
    }

    public removeNamespaceProperty_result deepCopy() {
      return new removeNamespaceProperty_result(this);
    }

    @Override
    public void clear() {
      this.ouch1 = null;
      this.ouch2 = null;
      this.ouch3 = null;
    }

    public AccumuloException getOuch1() {
      return this.ouch1;
    }

    public removeNamespaceProperty_result setOuch1(AccumuloException ouch1) {
      this.ouch1 = ouch1;
      return this;
    }

    public void unsetOuch1() {
      this.ouch1 = null;
    }

    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch1() {
      return this.ouch1 != null;
    }

    public void setOuch1IsSet(boolean value) {
      if (!value) {
        this.ouch1 = null;
      }
    }

    public AccumuloSecurityException getOuch2() {
      return this.ouch2;
    }

    public removeNamespaceProperty_result setOuch2(AccumuloSecurityException ouch2) {
      this.ouch2 = ouch2;
      return this;
    }

    public void unsetOuch2() {
      this.ouch2 = null;
    }

    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch2() {
      return this.ouch2 != null;
    }

    public void setOuch2IsSet(boolean value) {
      if (!value) {
        this.ouch2 = null;
      }
    }

    public NamespaceNotFoundException getOuch3() {
      return this.ouch3;
    }

    public removeNamespaceProperty_result setOuch3(NamespaceNotFoundException ouch3) {
      this.ouch3 = ouch3;
      return this;
    }

    public void unsetOuch3() {
      this.ouch3 = null;
    }

    /** Returns true if field ouch3 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch3() {
      return this.ouch3 != null;
    }

    public void setOuch3IsSet(boolean value) {
      if (!value) {
        this.ouch3 = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case OUCH1:
        if (value == null) {
          unsetOuch1();
        } else {
          setOuch1((AccumuloException)value);
        }
        break;

      case OUCH2:
        if (value == null) {
          unsetOuch2();
        } else {
          setOuch2((AccumuloSecurityException)value);
        }
        break;

      case OUCH3:
        if (value == null) {
          unsetOuch3();
        } else {
          setOuch3((NamespaceNotFoundException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case OUCH1:
        return getOuch1();

      case OUCH2:
        return getOuch2();

      case OUCH3:
        return getOuch3();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case OUCH1:
        return isSetOuch1();
      case OUCH2:
        return isSetOuch2();
      case OUCH3:
        return isSetOuch3();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof removeNamespaceProperty_result)
        return this.equals((removeNamespaceProperty_result)that);
      return false;
    }

    public boolean equals(removeNamespaceProperty_result that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_ouch1 = true && this.isSetOuch1();
      boolean that_present_ouch1 = true && that.isSetOuch1();
      if (this_present_ouch1 || that_present_ouch1) {
        if (!(this_present_ouch1 && that_present_ouch1))
          return false;
        if (!this.ouch1.equals(that.ouch1))
          return false;
      }

      boolean this_present_ouch2 = true && this.isSetOuch2();
      boolean that_present_ouch2 = true && that.isSetOuch2();
      if (this_present_ouch2 || that_present_ouch2) {
        if (!(this_present_ouch2 && that_present_ouch2))
          return false;
        if (!this.ouch2.equals(that.ouch2))
          return false;
      }

      boolean this_present_ouch3 = true && this.isSetOuch3();
      boolean that_present_ouch3 = true && that.isSetOuch3();
      if (this_present_ouch3 || that_present_ouch3) {
        if (!(this_present_ouch3 && that_present_ouch3))
          return false;
        if (!this.ouch3.equals(that.ouch3))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
      if (isSetOuch1())
        hashCode = hashCode * 8191 + ouch1.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
      if (isSetOuch2())
        hashCode = hashCode * 8191 + ouch2.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
      if (isSetOuch3())
        hashCode = hashCode * 8191 + ouch3.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(removeNamespaceProperty_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch1()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch2()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch3()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch3, other.ouch3);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("removeNamespaceProperty_result(");
      boolean first = true;

      sb.append("ouch1:");
      if (this.ouch1 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch1);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch2:");
      if (this.ouch2 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch2);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch3:");
      if (this.ouch3 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch3);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class removeNamespaceProperty_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public removeNamespaceProperty_resultStandardScheme getScheme() {
        return new removeNamespaceProperty_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // OUCH1
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch1 = new AccumuloException();
                struct.ouch1.read(iprot);
                struct.setOuch1IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OUCH2
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch2 = new AccumuloSecurityException();
                struct.ouch2.read(iprot);
                struct.setOuch2IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // OUCH3
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch3 = new NamespaceNotFoundException();
                struct.ouch3.read(iprot);
                struct.setOuch3IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, removeNamespaceProperty_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.ouch1 != null) {
          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
          struct.ouch1.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch2 != null) {
          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
          struct.ouch2.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch3 != null) {
          oprot.writeFieldBegin(OUCH3_FIELD_DESC);
          struct.ouch3.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class removeNamespaceProperty_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public removeNamespaceProperty_resultTupleScheme getScheme() {
        return new removeNamespaceProperty_resultTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetOuch2()) {
          optionals.set(1);
        }
        if (struct.isSetOuch3()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetOuch1()) {
          struct.ouch1.write(oprot);
        }
        if (struct.isSetOuch2()) {
          struct.ouch2.write(oprot);
        }
        if (struct.isSetOuch3()) {
          struct.ouch3.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, removeNamespaceProperty_result struct) throws org.apache.thrift.TException {
        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);
          struct.setOuch1IsSet(true);
        }
        if (incoming.get(1)) {
          struct.ouch2 = new AccumuloSecurityException();
          struct.ouch2.read(iprot);
          struct.setOuch2IsSet(true);
        }
        if (incoming.get(2)) {
          struct.ouch3 = new NamespaceNotFoundException();
          struct.ouch3.read(iprot);
          struct.setOuch3IsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getNamespaceProperties_args");

    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField NAMESPACE_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("namespaceName", org.apache.thrift.protocol.TType.STRING, (short)2);

    private static final 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 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 java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // LOGIN
            return LOGIN;
          case 2: // NAMESPACE_NAME
            return NAMESPACE_NAME;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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 = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getNamespaceProperties_args.class, metaDataMap);
    }

    public getNamespaceProperties_args() {
    }

    public getNamespaceProperties_args(
      java.nio.ByteBuffer login,
      java.lang.String namespaceName)
    {
      this();
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      this.namespaceName = namespaceName;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getNamespaceProperties_args(getNamespaceProperties_args other) {
      if (other.isSetLogin()) {
        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
      }
      if (other.isSetNamespaceName()) {
        this.namespaceName = other.namespaceName;
      }
    }

    public getNamespaceProperties_args deepCopy() {
      return new getNamespaceProperties_args(this);
    }

    @Override
    public void clear() {
      this.login = null;
      this.namespaceName = null;
    }

    public byte[] getLogin() {
      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
      return login == null ? null : login.array();
    }

    public java.nio.ByteBuffer bufferForLogin() {
      return org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    public getNamespaceProperties_args setLogin(byte[] login) {
      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
      return this;
    }

    public getNamespaceProperties_args setLogin(java.nio.ByteBuffer login) {
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      return this;
    }

    public void unsetLogin() {
      this.login = null;
    }

    /** Returns true if field login is set (has been assigned a value) and false otherwise */
    public boolean isSetLogin() {
      return this.login != null;
    }

    public void setLoginIsSet(boolean value) {
      if (!value) {
        this.login = null;
      }
    }

    public java.lang.String getNamespaceName() {
      return this.namespaceName;
    }

    public getNamespaceProperties_args setNamespaceName(java.lang.String namespaceName) {
      this.namespaceName = namespaceName;
      return this;
    }

    public void unsetNamespaceName() {
      this.namespaceName = null;
    }

    /** Returns true if field namespaceName is set (has been assigned a value) and false otherwise */
    public boolean isSetNamespaceName() {
      return this.namespaceName != null;
    }

    public void setNamespaceNameIsSet(boolean value) {
      if (!value) {
        this.namespaceName = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case LOGIN:
        if (value == null) {
          unsetLogin();
        } else {
          if (value instanceof byte[]) {
            setLogin((byte[])value);
          } else {
            setLogin((java.nio.ByteBuffer)value);
          }
        }
        break;

      case NAMESPACE_NAME:
        if (value == null) {
          unsetNamespaceName();
        } else {
          setNamespaceName((java.lang.String)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case LOGIN:
        return getLogin();

      case NAMESPACE_NAME:
        return getNamespaceName();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case LOGIN:
        return isSetLogin();
      case NAMESPACE_NAME:
        return isSetNamespaceName();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof getNamespaceProperties_args)
        return this.equals((getNamespaceProperties_args)that);
      return false;
    }

    public boolean equals(getNamespaceProperties_args that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_login = true && this.isSetLogin();
      boolean that_present_login = true && that.isSetLogin();
      if (this_present_login || that_present_login) {
        if (!(this_present_login && that_present_login))
          return false;
        if (!this.login.equals(that.login))
          return false;
      }

      boolean this_present_namespaceName = true && this.isSetNamespaceName();
      boolean that_present_namespaceName = true && that.isSetNamespaceName();
      if (this_present_namespaceName || that_present_namespaceName) {
        if (!(this_present_namespaceName && that_present_namespaceName))
          return false;
        if (!this.namespaceName.equals(that.namespaceName))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
      if (isSetLogin())
        hashCode = hashCode * 8191 + login.hashCode();

      hashCode = hashCode * 8191 + ((isSetNamespaceName()) ? 131071 : 524287);
      if (isSetNamespaceName())
        hashCode = hashCode * 8191 + namespaceName.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(getNamespaceProperties_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLogin()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetNamespaceName()).compareTo(other.isSetNamespaceName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetNamespaceName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.namespaceName, other.namespaceName);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("getNamespaceProperties_args(");
      boolean first = true;

      sb.append("login:");
      if (this.login == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.login, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("namespaceName:");
      if (this.namespaceName == null) {
        sb.append("null");
      } else {
        sb.append(this.namespaceName);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class getNamespaceProperties_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getNamespaceProperties_argsStandardScheme getScheme() {
        return new getNamespaceProperties_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // LOGIN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.login = iprot.readBinary();
                struct.setLoginIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // NAMESPACE_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.namespaceName = iprot.readString();
                struct.setNamespaceNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getNamespaceProperties_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.login != null) {
          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
          oprot.writeBinary(struct.login);
          oprot.writeFieldEnd();
        }
        if (struct.namespaceName != null) {
          oprot.writeFieldBegin(NAMESPACE_NAME_FIELD_DESC);
          oprot.writeString(struct.namespaceName);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getNamespaceProperties_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getNamespaceProperties_argsTupleScheme getScheme() {
        return new getNamespaceProperties_argsTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetNamespaceName()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetLogin()) {
          oprot.writeBinary(struct.login);
        }
        if (struct.isSetNamespaceName()) {
          oprot.writeString(struct.namespaceName);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getNamespaceProperties_args struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.namespaceName = iprot.readString();
          struct.setNamespaceNameIsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getNamespaceProperties_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.MAP, (short)0);
    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField OUCH3_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch3", org.apache.thrift.protocol.TType.STRUCT, (short)3);

    private static final 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 java.util.Map<java.lang.String,java.lang.String> success; // required
    public AccumuloException ouch1; // required
    public AccumuloSecurityException ouch2; // required
    public NamespaceNotFoundException ouch3; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      OUCH1((short)1, "ouch1"),
      OUCH2((short)2, "ouch2"),
      OUCH3((short)3, "ouch3");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // OUCH1
            return OUCH1;
          case 2: // OUCH2
            return OUCH2;
          case 3: // OUCH3
            return OUCH3;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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.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.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);
    }

    public getNamespaceProperties_result() {
    }

    public getNamespaceProperties_result(
      java.util.Map<java.lang.String,java.lang.String> success,
      AccumuloException ouch1,
      AccumuloSecurityException ouch2,
      NamespaceNotFoundException ouch3)
    {
      this();
      this.success = success;
      this.ouch1 = ouch1;
      this.ouch2 = ouch2;
      this.ouch3 = ouch3;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getNamespaceProperties_result(getNamespaceProperties_result other) {
      if (other.isSetSuccess()) {
        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()) {
        this.ouch1 = new AccumuloException(other.ouch1);
      }
      if (other.isSetOuch2()) {
        this.ouch2 = new AccumuloSecurityException(other.ouch2);
      }
      if (other.isSetOuch3()) {
        this.ouch3 = new NamespaceNotFoundException(other.ouch3);
      }
    }

    public getNamespaceProperties_result deepCopy() {
      return new getNamespaceProperties_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ouch1 = null;
      this.ouch2 = null;
      this.ouch3 = null;
    }

    public int getSuccessSize() {
      return (this.success == null) ? 0 : this.success.size();
    }

    public void putToSuccess(java.lang.String key, java.lang.String val) {
      if (this.success == null) {
        this.success = new java.util.HashMap<java.lang.String,java.lang.String>();
      }
      this.success.put(key, val);
    }

    public java.util.Map<java.lang.String,java.lang.String> getSuccess() {
      return this.success;
    }

    public getNamespaceProperties_result setSuccess(java.util.Map<java.lang.String,java.lang.String> success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return this.success != null;
    }

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public AccumuloException getOuch1() {
      return this.ouch1;
    }

    public getNamespaceProperties_result setOuch1(AccumuloException ouch1) {
      this.ouch1 = ouch1;
      return this;
    }

    public void unsetOuch1() {
      this.ouch1 = null;
    }

    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch1() {
      return this.ouch1 != null;
    }

    public void setOuch1IsSet(boolean value) {
      if (!value) {
        this.ouch1 = null;
      }
    }

    public AccumuloSecurityException getOuch2() {
      return this.ouch2;
    }

    public getNamespaceProperties_result setOuch2(AccumuloSecurityException ouch2) {
      this.ouch2 = ouch2;
      return this;
    }

    public void unsetOuch2() {
      this.ouch2 = null;
    }

    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch2() {
      return this.ouch2 != null;
    }

    public void setOuch2IsSet(boolean value) {
      if (!value) {
        this.ouch2 = null;
      }
    }

    public NamespaceNotFoundException getOuch3() {
      return this.ouch3;
    }

    public getNamespaceProperties_result setOuch3(NamespaceNotFoundException ouch3) {
      this.ouch3 = ouch3;
      return this;
    }

    public void unsetOuch3() {
      this.ouch3 = null;
    }

    /** Returns true if field ouch3 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch3() {
      return this.ouch3 != null;
    }

    public void setOuch3IsSet(boolean value) {
      if (!value) {
        this.ouch3 = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.util.Map<java.lang.String,java.lang.String>)value);
        }
        break;

      case OUCH1:
        if (value == null) {
          unsetOuch1();
        } else {
          setOuch1((AccumuloException)value);
        }
        break;

      case OUCH2:
        if (value == null) {
          unsetOuch2();
        } else {
          setOuch2((AccumuloSecurityException)value);
        }
        break;

      case OUCH3:
        if (value == null) {
          unsetOuch3();
        } else {
          setOuch3((NamespaceNotFoundException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case OUCH1:
        return getOuch1();

      case OUCH2:
        return getOuch2();

      case OUCH3:
        return getOuch3();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case OUCH1:
        return isSetOuch1();
      case OUCH2:
        return isSetOuch2();
      case OUCH3:
        return isSetOuch3();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof getNamespaceProperties_result)
        return this.equals((getNamespaceProperties_result)that);
      return false;
    }

    public boolean equals(getNamespaceProperties_result that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ouch1 = true && this.isSetOuch1();
      boolean that_present_ouch1 = true && that.isSetOuch1();
      if (this_present_ouch1 || that_present_ouch1) {
        if (!(this_present_ouch1 && that_present_ouch1))
          return false;
        if (!this.ouch1.equals(that.ouch1))
          return false;
      }

      boolean this_present_ouch2 = true && this.isSetOuch2();
      boolean that_present_ouch2 = true && that.isSetOuch2();
      if (this_present_ouch2 || that_present_ouch2) {
        if (!(this_present_ouch2 && that_present_ouch2))
          return false;
        if (!this.ouch2.equals(that.ouch2))
          return false;
      }

      boolean this_present_ouch3 = true && this.isSetOuch3();
      boolean that_present_ouch3 = true && that.isSetOuch3();
      if (this_present_ouch3 || that_present_ouch3) {
        if (!(this_present_ouch3 && that_present_ouch3))
          return false;
        if (!this.ouch3.equals(that.ouch3))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
      if (isSetSuccess())
        hashCode = hashCode * 8191 + success.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
      if (isSetOuch1())
        hashCode = hashCode * 8191 + ouch1.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
      if (isSetOuch2())
        hashCode = hashCode * 8191 + ouch2.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
      if (isSetOuch3())
        hashCode = hashCode * 8191 + ouch3.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(getNamespaceProperties_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch1()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch2()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch3()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch3, other.ouch3);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("getNamespaceProperties_result(");
      boolean first = true;

      sb.append("success:");
      if (this.success == null) {
        sb.append("null");
      } else {
        sb.append(this.success);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch1:");
      if (this.ouch1 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch1);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch2:");
      if (this.ouch2 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch2);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch3:");
      if (this.ouch3 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch3);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class getNamespaceProperties_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getNamespaceProperties_resultStandardScheme getScheme() {
        return new getNamespaceProperties_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.MAP) {
                {
                  org.apache.thrift.protocol.TMap _map506 = iprot.readMapBegin();
                  struct.success = new 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();
                    _val508 = iprot.readString();
                    struct.success.put(_key507, _val508);
                  }
                  iprot.readMapEnd();
                }
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // OUCH1
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch1 = new AccumuloException();
                struct.ouch1.read(iprot);
                struct.setOuch1IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OUCH2
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch2 = new AccumuloSecurityException();
                struct.ouch2.read(iprot);
                struct.setOuch2IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // OUCH3
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch3 = new NamespaceNotFoundException();
                struct.ouch3.read(iprot);
                struct.setOuch3IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getNamespaceProperties_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          {
            oprot.writeMapBegin(new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.STRING, struct.success.size()));
            for (java.util.Map.Entry<java.lang.String, java.lang.String> _iter510 : struct.success.entrySet())
            {
              oprot.writeString(_iter510.getKey());
              oprot.writeString(_iter510.getValue());
            }
            oprot.writeMapEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.ouch1 != null) {
          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
          struct.ouch1.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch2 != null) {
          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
          struct.ouch2.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch3 != null) {
          oprot.writeFieldBegin(OUCH3_FIELD_DESC);
          struct.ouch3.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getNamespaceProperties_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getNamespaceProperties_resultTupleScheme getScheme() {
        return new getNamespaceProperties_resultTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetOuch1()) {
          optionals.set(1);
        }
        if (struct.isSetOuch2()) {
          optionals.set(2);
        }
        if (struct.isSetOuch3()) {
          optionals.set(3);
        }
        oprot.writeBitSet(optionals, 4);
        if (struct.isSetSuccess()) {
          {
            oprot.writeI32(struct.success.size());
            for (java.util.Map.Entry<java.lang.String, java.lang.String> _iter511 : struct.success.entrySet())
            {
              oprot.writeString(_iter511.getKey());
              oprot.writeString(_iter511.getValue());
            }
          }
        }
        if (struct.isSetOuch1()) {
          struct.ouch1.write(oprot);
        }
        if (struct.isSetOuch2()) {
          struct.ouch2.write(oprot);
        }
        if (struct.isSetOuch3()) {
          struct.ouch3.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getNamespaceProperties_result struct) throws org.apache.thrift.TException {
        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 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();
              _val514 = iprot.readString();
              struct.success.put(_key513, _val514);
            }
          }
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ouch1 = new AccumuloException();
          struct.ouch1.read(iprot);
          struct.setOuch1IsSet(true);
        }
        if (incoming.get(2)) {
          struct.ouch2 = new AccumuloSecurityException();
          struct.ouch2.read(iprot);
          struct.setOuch2IsSet(true);
        }
        if (incoming.get(3)) {
          struct.ouch3 = new NamespaceNotFoundException();
          struct.ouch3.read(iprot);
          struct.setOuch3IsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("namespaceIdMap_args");

    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);

    private static final 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 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 java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // LOGIN
            return LOGIN;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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 = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(namespaceIdMap_args.class, metaDataMap);
    }

    public namespaceIdMap_args() {
    }

    public namespaceIdMap_args(
      java.nio.ByteBuffer login)
    {
      this();
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public namespaceIdMap_args(namespaceIdMap_args other) {
      if (other.isSetLogin()) {
        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
      }
    }

    public namespaceIdMap_args deepCopy() {
      return new namespaceIdMap_args(this);
    }

    @Override
    public void clear() {
      this.login = null;
    }

    public byte[] getLogin() {
      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
      return login == null ? null : login.array();
    }

    public java.nio.ByteBuffer bufferForLogin() {
      return org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    public namespaceIdMap_args setLogin(byte[] login) {
      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
      return this;
    }

    public namespaceIdMap_args setLogin(java.nio.ByteBuffer login) {
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      return this;
    }

    public void unsetLogin() {
      this.login = null;
    }

    /** Returns true if field login is set (has been assigned a value) and false otherwise */
    public boolean isSetLogin() {
      return this.login != null;
    }

    public void setLoginIsSet(boolean value) {
      if (!value) {
        this.login = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case LOGIN:
        if (value == null) {
          unsetLogin();
        } else {
          if (value instanceof byte[]) {
            setLogin((byte[])value);
          } else {
            setLogin((java.nio.ByteBuffer)value);
          }
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case LOGIN:
        return getLogin();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case LOGIN:
        return isSetLogin();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof namespaceIdMap_args)
        return this.equals((namespaceIdMap_args)that);
      return false;
    }

    public boolean equals(namespaceIdMap_args that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_login = true && this.isSetLogin();
      boolean that_present_login = true && that.isSetLogin();
      if (this_present_login || that_present_login) {
        if (!(this_present_login && that_present_login))
          return false;
        if (!this.login.equals(that.login))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
      if (isSetLogin())
        hashCode = hashCode * 8191 + login.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(namespaceIdMap_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLogin()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("namespaceIdMap_args(");
      boolean first = true;

      sb.append("login:");
      if (this.login == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.login, sb);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class namespaceIdMap_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public namespaceIdMap_argsStandardScheme getScheme() {
        return new namespaceIdMap_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // LOGIN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.login = iprot.readBinary();
                struct.setLoginIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, namespaceIdMap_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.login != null) {
          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
          oprot.writeBinary(struct.login);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class namespaceIdMap_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public namespaceIdMap_argsTupleScheme getScheme() {
        return new namespaceIdMap_argsTupleScheme();
      }
    }

    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 {
        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);
        }
        oprot.writeBitSet(optionals, 1);
        if (struct.isSetLogin()) {
          oprot.writeBinary(struct.login);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, namespaceIdMap_args struct) throws org.apache.thrift.TException {
        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);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("namespaceIdMap_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.MAP, (short)0);
    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);

    private static final 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 java.util.Map<java.lang.String,java.lang.String> success; // required
    public AccumuloException ouch1; // required
    public AccumuloSecurityException ouch2; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      OUCH1((short)1, "ouch1"),
      OUCH2((short)2, "ouch2");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // OUCH1
            return OUCH1;
          case 2: // OUCH2
            return OUCH2;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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.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);
    }

    public namespaceIdMap_result() {
    }

    public namespaceIdMap_result(
      java.util.Map<java.lang.String,java.lang.String> success,
      AccumuloException ouch1,
      AccumuloSecurityException ouch2)
    {
      this();
      this.success = success;
      this.ouch1 = ouch1;
      this.ouch2 = ouch2;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public namespaceIdMap_result(namespaceIdMap_result other) {
      if (other.isSetSuccess()) {
        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()) {
        this.ouch1 = new AccumuloException(other.ouch1);
      }
      if (other.isSetOuch2()) {
        this.ouch2 = new AccumuloSecurityException(other.ouch2);
      }
    }

    public namespaceIdMap_result deepCopy() {
      return new namespaceIdMap_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ouch1 = null;
      this.ouch2 = null;
    }

    public int getSuccessSize() {
      return (this.success == null) ? 0 : this.success.size();
    }

    public void putToSuccess(java.lang.String key, java.lang.String val) {
      if (this.success == null) {
        this.success = new java.util.HashMap<java.lang.String,java.lang.String>();
      }
      this.success.put(key, val);
    }

    public java.util.Map<java.lang.String,java.lang.String> getSuccess() {
      return this.success;
    }

    public namespaceIdMap_result setSuccess(java.util.Map<java.lang.String,java.lang.String> success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return this.success != null;
    }

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public AccumuloException getOuch1() {
      return this.ouch1;
    }

    public namespaceIdMap_result setOuch1(AccumuloException ouch1) {
      this.ouch1 = ouch1;
      return this;
    }

    public void unsetOuch1() {
      this.ouch1 = null;
    }

    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch1() {
      return this.ouch1 != null;
    }

    public void setOuch1IsSet(boolean value) {
      if (!value) {
        this.ouch1 = null;
      }
    }

    public AccumuloSecurityException getOuch2() {
      return this.ouch2;
    }

    public namespaceIdMap_result setOuch2(AccumuloSecurityException ouch2) {
      this.ouch2 = ouch2;
      return this;
    }

    public void unsetOuch2() {
      this.ouch2 = null;
    }

    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch2() {
      return this.ouch2 != null;
    }

    public void setOuch2IsSet(boolean value) {
      if (!value) {
        this.ouch2 = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.util.Map<java.lang.String,java.lang.String>)value);
        }
        break;

      case OUCH1:
        if (value == null) {
          unsetOuch1();
        } else {
          setOuch1((AccumuloException)value);
        }
        break;

      case OUCH2:
        if (value == null) {
          unsetOuch2();
        } else {
          setOuch2((AccumuloSecurityException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case OUCH1:
        return getOuch1();

      case OUCH2:
        return getOuch2();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case OUCH1:
        return isSetOuch1();
      case OUCH2:
        return isSetOuch2();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof namespaceIdMap_result)
        return this.equals((namespaceIdMap_result)that);
      return false;
    }

    public boolean equals(namespaceIdMap_result that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ouch1 = true && this.isSetOuch1();
      boolean that_present_ouch1 = true && that.isSetOuch1();
      if (this_present_ouch1 || that_present_ouch1) {
        if (!(this_present_ouch1 && that_present_ouch1))
          return false;
        if (!this.ouch1.equals(that.ouch1))
          return false;
      }

      boolean this_present_ouch2 = true && this.isSetOuch2();
      boolean that_present_ouch2 = true && that.isSetOuch2();
      if (this_present_ouch2 || that_present_ouch2) {
        if (!(this_present_ouch2 && that_present_ouch2))
          return false;
        if (!this.ouch2.equals(that.ouch2))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
      if (isSetSuccess())
        hashCode = hashCode * 8191 + success.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
      if (isSetOuch1())
        hashCode = hashCode * 8191 + ouch1.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
      if (isSetOuch2())
        hashCode = hashCode * 8191 + ouch2.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(namespaceIdMap_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch1()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch2()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("namespaceIdMap_result(");
      boolean first = true;

      sb.append("success:");
      if (this.success == null) {
        sb.append("null");
      } else {
        sb.append(this.success);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch1:");
      if (this.ouch1 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch1);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch2:");
      if (this.ouch2 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch2);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class namespaceIdMap_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public namespaceIdMap_resultStandardScheme getScheme() {
        return new namespaceIdMap_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.MAP) {
                {
                  org.apache.thrift.protocol.TMap _map516 = iprot.readMapBegin();
                  struct.success = new 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();
                    _val518 = iprot.readString();
                    struct.success.put(_key517, _val518);
                  }
                  iprot.readMapEnd();
                }
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // OUCH1
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch1 = new AccumuloException();
                struct.ouch1.read(iprot);
                struct.setOuch1IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OUCH2
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch2 = new AccumuloSecurityException();
                struct.ouch2.read(iprot);
                struct.setOuch2IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, namespaceIdMap_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          {
            oprot.writeMapBegin(new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.STRING, struct.success.size()));
            for (java.util.Map.Entry<java.lang.String, java.lang.String> _iter520 : struct.success.entrySet())
            {
              oprot.writeString(_iter520.getKey());
              oprot.writeString(_iter520.getValue());
            }
            oprot.writeMapEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.ouch1 != null) {
          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
          struct.ouch1.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch2 != null) {
          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
          struct.ouch2.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class namespaceIdMap_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public namespaceIdMap_resultTupleScheme getScheme() {
        return new namespaceIdMap_resultTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetOuch1()) {
          optionals.set(1);
        }
        if (struct.isSetOuch2()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetSuccess()) {
          {
            oprot.writeI32(struct.success.size());
            for (java.util.Map.Entry<java.lang.String, java.lang.String> _iter521 : struct.success.entrySet())
            {
              oprot.writeString(_iter521.getKey());
              oprot.writeString(_iter521.getValue());
            }
          }
        }
        if (struct.isSetOuch1()) {
          struct.ouch1.write(oprot);
        }
        if (struct.isSetOuch2()) {
          struct.ouch2.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, namespaceIdMap_result struct) throws org.apache.thrift.TException {
        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 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();
              _val524 = iprot.readString();
              struct.success.put(_key523, _val524);
            }
          }
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ouch1 = new AccumuloException();
          struct.ouch1.read(iprot);
          struct.setOuch1IsSet(true);
        }
        if (incoming.get(2)) {
          struct.ouch2 = new AccumuloSecurityException();
          struct.ouch2.read(iprot);
          struct.setOuch2IsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("attachNamespaceIterator_args");

    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField NAMESPACE_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("namespaceName", org.apache.thrift.protocol.TType.STRING, (short)2);
    private static final org.apache.thrift.protocol.TField SETTING_FIELD_DESC = new org.apache.thrift.protocol.TField("setting", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    private static final org.apache.thrift.protocol.TField SCOPES_FIELD_DESC = new org.apache.thrift.protocol.TField("scopes", org.apache.thrift.protocol.TType.SET, (short)4);

    private static final 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 java.nio.ByteBuffer login; // required
    public java.lang.String namespaceName; // required
    public IteratorSetting setting; // 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 {
      LOGIN((short)1, "login"),
      NAMESPACE_NAME((short)2, "namespaceName"),
      SETTING((short)3, "setting"),
      SCOPES((short)4, "scopes");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // LOGIN
            return LOGIN;
          case 2: // NAMESPACE_NAME
            return NAMESPACE_NAME;
          case 3: // SETTING
            return SETTING;
          case 4: // SCOPES
            return SCOPES;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.SETTING, new org.apache.thrift.meta_data.FieldMetaData("setting", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, IteratorSetting.class)));
      tmpMap.put(_Fields.SCOPES, new org.apache.thrift.meta_data.FieldMetaData("scopes", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.SetMetaData(org.apache.thrift.protocol.TType.SET, 
              new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, IteratorScope.class))));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(attachNamespaceIterator_args.class, metaDataMap);
    }

    public attachNamespaceIterator_args() {
    }

    public attachNamespaceIterator_args(
      java.nio.ByteBuffer login,
      java.lang.String namespaceName,
      IteratorSetting setting,
      java.util.Set<IteratorScope> scopes)
    {
      this();
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      this.namespaceName = namespaceName;
      this.setting = setting;
      this.scopes = scopes;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public attachNamespaceIterator_args(attachNamespaceIterator_args other) {
      if (other.isSetLogin()) {
        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
      }
      if (other.isSetNamespaceName()) {
        this.namespaceName = other.namespaceName;
      }
      if (other.isSetSetting()) {
        this.setting = new IteratorSetting(other.setting);
      }
      if (other.isSetScopes()) {
        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);
        }
        this.scopes = __this__scopes;
      }
    }

    public attachNamespaceIterator_args deepCopy() {
      return new attachNamespaceIterator_args(this);
    }

    @Override
    public void clear() {
      this.login = null;
      this.namespaceName = null;
      this.setting = null;
      this.scopes = null;
    }

    public byte[] getLogin() {
      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
      return login == null ? null : login.array();
    }

    public java.nio.ByteBuffer bufferForLogin() {
      return org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    public attachNamespaceIterator_args setLogin(byte[] login) {
      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
      return this;
    }

    public attachNamespaceIterator_args setLogin(java.nio.ByteBuffer login) {
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      return this;
    }

    public void unsetLogin() {
      this.login = null;
    }

    /** Returns true if field login is set (has been assigned a value) and false otherwise */
    public boolean isSetLogin() {
      return this.login != null;
    }

    public void setLoginIsSet(boolean value) {
      if (!value) {
        this.login = null;
      }
    }

    public java.lang.String getNamespaceName() {
      return this.namespaceName;
    }

    public attachNamespaceIterator_args setNamespaceName(java.lang.String namespaceName) {
      this.namespaceName = namespaceName;
      return this;
    }

    public void unsetNamespaceName() {
      this.namespaceName = null;
    }

    /** Returns true if field namespaceName is set (has been assigned a value) and false otherwise */
    public boolean isSetNamespaceName() {
      return this.namespaceName != null;
    }

    public void setNamespaceNameIsSet(boolean value) {
      if (!value) {
        this.namespaceName = null;
      }
    }

    public IteratorSetting getSetting() {
      return this.setting;
    }

    public attachNamespaceIterator_args setSetting(IteratorSetting setting) {
      this.setting = setting;
      return this;
    }

    public void unsetSetting() {
      this.setting = null;
    }

    /** Returns true if field setting is set (has been assigned a value) and false otherwise */
    public boolean isSetSetting() {
      return this.setting != null;
    }

    public void setSettingIsSet(boolean value) {
      if (!value) {
        this.setting = null;
      }
    }

    public int getScopesSize() {
      return (this.scopes == null) ? 0 : this.scopes.size();
    }

    public java.util.Iterator<IteratorScope> getScopesIterator() {
      return (this.scopes == null) ? null : this.scopes.iterator();
    }

    public void addToScopes(IteratorScope elem) {
      if (this.scopes == null) {
        this.scopes = new java.util.HashSet<IteratorScope>();
      }
      this.scopes.add(elem);
    }

    public java.util.Set<IteratorScope> getScopes() {
      return this.scopes;
    }

    public attachNamespaceIterator_args setScopes(java.util.Set<IteratorScope> scopes) {
      this.scopes = scopes;
      return this;
    }

    public void unsetScopes() {
      this.scopes = null;
    }

    /** Returns true if field scopes is set (has been assigned a value) and false otherwise */
    public boolean isSetScopes() {
      return this.scopes != null;
    }

    public void setScopesIsSet(boolean value) {
      if (!value) {
        this.scopes = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case LOGIN:
        if (value == null) {
          unsetLogin();
        } else {
          if (value instanceof byte[]) {
            setLogin((byte[])value);
          } else {
            setLogin((java.nio.ByteBuffer)value);
          }
        }
        break;

      case NAMESPACE_NAME:
        if (value == null) {
          unsetNamespaceName();
        } else {
          setNamespaceName((java.lang.String)value);
        }
        break;

      case SETTING:
        if (value == null) {
          unsetSetting();
        } else {
          setSetting((IteratorSetting)value);
        }
        break;

      case SCOPES:
        if (value == null) {
          unsetScopes();
        } else {
          setScopes((java.util.Set<IteratorScope>)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case LOGIN:
        return getLogin();

      case NAMESPACE_NAME:
        return getNamespaceName();

      case SETTING:
        return getSetting();

      case SCOPES:
        return getScopes();

      }
      throw new 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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case LOGIN:
        return isSetLogin();
      case NAMESPACE_NAME:
        return isSetNamespaceName();
      case SETTING:
        return isSetSetting();
      case SCOPES:
        return isSetScopes();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof attachNamespaceIterator_args)
        return this.equals((attachNamespaceIterator_args)that);
      return false;
    }

    public boolean equals(attachNamespaceIterator_args that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_login = true && this.isSetLogin();
      boolean that_present_login = true && that.isSetLogin();
      if (this_present_login || that_present_login) {
        if (!(this_present_login && that_present_login))
          return false;
        if (!this.login.equals(that.login))
          return false;
      }

      boolean this_present_namespaceName = true && this.isSetNamespaceName();
      boolean that_present_namespaceName = true && that.isSetNamespaceName();
      if (this_present_namespaceName || that_present_namespaceName) {
        if (!(this_present_namespaceName && that_present_namespaceName))
          return false;
        if (!this.namespaceName.equals(that.namespaceName))
          return false;
      }

      boolean this_present_setting = true && this.isSetSetting();
      boolean that_present_setting = true && that.isSetSetting();
      if (this_present_setting || that_present_setting) {
        if (!(this_present_setting && that_present_setting))
          return false;
        if (!this.setting.equals(that.setting))
          return false;
      }

      boolean this_present_scopes = true && this.isSetScopes();
      boolean that_present_scopes = true && that.isSetScopes();
      if (this_present_scopes || that_present_scopes) {
        if (!(this_present_scopes && that_present_scopes))
          return false;
        if (!this.scopes.equals(that.scopes))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
      if (isSetLogin())
        hashCode = hashCode * 8191 + login.hashCode();

      hashCode = hashCode * 8191 + ((isSetNamespaceName()) ? 131071 : 524287);
      if (isSetNamespaceName())
        hashCode = hashCode * 8191 + namespaceName.hashCode();

      hashCode = hashCode * 8191 + ((isSetSetting()) ? 131071 : 524287);
      if (isSetSetting())
        hashCode = hashCode * 8191 + setting.hashCode();

      hashCode = hashCode * 8191 + ((isSetScopes()) ? 131071 : 524287);
      if (isSetScopes())
        hashCode = hashCode * 8191 + scopes.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(attachNamespaceIterator_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLogin()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetNamespaceName()).compareTo(other.isSetNamespaceName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetNamespaceName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.namespaceName, other.namespaceName);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetSetting()).compareTo(other.isSetSetting());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSetting()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.setting, other.setting);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetScopes()).compareTo(other.isSetScopes());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetScopes()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.scopes, other.scopes);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("attachNamespaceIterator_args(");
      boolean first = true;

      sb.append("login:");
      if (this.login == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.login, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("namespaceName:");
      if (this.namespaceName == null) {
        sb.append("null");
      } else {
        sb.append(this.namespaceName);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("setting:");
      if (this.setting == null) {
        sb.append("null");
      } else {
        sb.append(this.setting);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("scopes:");
      if (this.scopes == null) {
        sb.append("null");
      } else {
        sb.append(this.scopes);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
      if (setting != null) {
        setting.validate();
      }
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class attachNamespaceIterator_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public attachNamespaceIterator_argsStandardScheme getScheme() {
        return new attachNamespaceIterator_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // LOGIN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.login = iprot.readBinary();
                struct.setLoginIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // NAMESPACE_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.namespaceName = iprot.readString();
                struct.setNamespaceNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // SETTING
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.setting = new IteratorSetting();
                struct.setting.read(iprot);
                struct.setSettingIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // SCOPES
              if (schemeField.type == org.apache.thrift.protocol.TType.SET) {
                {
                  org.apache.thrift.protocol.TSet _set526 = iprot.readSetBegin();
                  struct.scopes = new java.util.HashSet<IteratorScope>(2*_set526.size);
                  IteratorScope _elem527;
                  for (int _i528 = 0; _i528 < _set526.size; ++_i528)
                  {
                    _elem527 = org.apache.accumulo.proxy.thrift.IteratorScope.findByValue(iprot.readI32());
                    struct.scopes.add(_elem527);
                  }
                  iprot.readSetEnd();
                }
                struct.setScopesIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, attachNamespaceIterator_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.login != null) {
          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
          oprot.writeBinary(struct.login);
          oprot.writeFieldEnd();
        }
        if (struct.namespaceName != null) {
          oprot.writeFieldBegin(NAMESPACE_NAME_FIELD_DESC);
          oprot.writeString(struct.namespaceName);
          oprot.writeFieldEnd();
        }
        if (struct.setting != null) {
          oprot.writeFieldBegin(SETTING_FIELD_DESC);
          struct.setting.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.scopes != null) {
          oprot.writeFieldBegin(SCOPES_FIELD_DESC);
          {
            oprot.writeSetBegin(new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.I32, struct.scopes.size()));
            for (IteratorScope _iter529 : struct.scopes)
            {
              oprot.writeI32(_iter529.getValue());
            }
            oprot.writeSetEnd();
          }
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class attachNamespaceIterator_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public attachNamespaceIterator_argsTupleScheme getScheme() {
        return new attachNamespaceIterator_argsTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetNamespaceName()) {
          optionals.set(1);
        }
        if (struct.isSetSetting()) {
          optionals.set(2);
        }
        if (struct.isSetScopes()) {
          optionals.set(3);
        }
        oprot.writeBitSet(optionals, 4);
        if (struct.isSetLogin()) {
          oprot.writeBinary(struct.login);
        }
        if (struct.isSetNamespaceName()) {
          oprot.writeString(struct.namespaceName);
        }
        if (struct.isSetSetting()) {
          struct.setting.write(oprot);
        }
        if (struct.isSetScopes()) {
          {
            oprot.writeI32(struct.scopes.size());
            for (IteratorScope _iter530 : struct.scopes)
            {
              oprot.writeI32(_iter530.getValue());
            }
          }
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, attachNamespaceIterator_args struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.namespaceName = iprot.readString();
          struct.setNamespaceNameIsSet(true);
        }
        if (incoming.get(2)) {
          struct.setting = new IteratorSetting();
          struct.setting.read(iprot);
          struct.setSettingIsSet(true);
        }
        if (incoming.get(3)) {
          {
            org.apache.thrift.protocol.TSet _set531 = new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.I32, iprot.readI32());
            struct.scopes = new java.util.HashSet<IteratorScope>(2*_set531.size);
            IteratorScope _elem532;
            for (int _i533 = 0; _i533 < _set531.size; ++_i533)
            {
              _elem532 = org.apache.accumulo.proxy.thrift.IteratorScope.findByValue(iprot.readI32());
              struct.scopes.add(_elem532);
            }
          }
          struct.setScopesIsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("attachNamespaceIterator_result");

    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField OUCH3_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch3", org.apache.thrift.protocol.TType.STRUCT, (short)3);

    private static final 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
    public NamespaceNotFoundException ouch3; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      OUCH1((short)1, "ouch1"),
      OUCH2((short)2, "ouch2"),
      OUCH3((short)3, "ouch3");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // OUCH1
            return OUCH1;
          case 2: // OUCH2
            return OUCH2;
          case 3: // OUCH3
            return OUCH3;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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.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.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);
    }

    public attachNamespaceIterator_result() {
    }

    public attachNamespaceIterator_result(
      AccumuloException ouch1,
      AccumuloSecurityException ouch2,
      NamespaceNotFoundException ouch3)
    {
      this();
      this.ouch1 = ouch1;
      this.ouch2 = ouch2;
      this.ouch3 = ouch3;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public attachNamespaceIterator_result(attachNamespaceIterator_result other) {
      if (other.isSetOuch1()) {
        this.ouch1 = new AccumuloException(other.ouch1);
      }
      if (other.isSetOuch2()) {
        this.ouch2 = new AccumuloSecurityException(other.ouch2);
      }
      if (other.isSetOuch3()) {
        this.ouch3 = new NamespaceNotFoundException(other.ouch3);
      }
    }

    public attachNamespaceIterator_result deepCopy() {
      return new attachNamespaceIterator_result(this);
    }

    @Override
    public void clear() {
      this.ouch1 = null;
      this.ouch2 = null;
      this.ouch3 = null;
    }

    public AccumuloException getOuch1() {
      return this.ouch1;
    }

    public attachNamespaceIterator_result setOuch1(AccumuloException ouch1) {
      this.ouch1 = ouch1;
      return this;
    }

    public void unsetOuch1() {
      this.ouch1 = null;
    }

    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch1() {
      return this.ouch1 != null;
    }

    public void setOuch1IsSet(boolean value) {
      if (!value) {
        this.ouch1 = null;
      }
    }

    public AccumuloSecurityException getOuch2() {
      return this.ouch2;
    }

    public attachNamespaceIterator_result setOuch2(AccumuloSecurityException ouch2) {
      this.ouch2 = ouch2;
      return this;
    }

    public void unsetOuch2() {
      this.ouch2 = null;
    }

    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch2() {
      return this.ouch2 != null;
    }

    public void setOuch2IsSet(boolean value) {
      if (!value) {
        this.ouch2 = null;
      }
    }

    public NamespaceNotFoundException getOuch3() {
      return this.ouch3;
    }

    public attachNamespaceIterator_result setOuch3(NamespaceNotFoundException ouch3) {
      this.ouch3 = ouch3;
      return this;
    }

    public void unsetOuch3() {
      this.ouch3 = null;
    }

    /** Returns true if field ouch3 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch3() {
      return this.ouch3 != null;
    }

    public void setOuch3IsSet(boolean value) {
      if (!value) {
        this.ouch3 = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case OUCH1:
        if (value == null) {
          unsetOuch1();
        } else {
          setOuch1((AccumuloException)value);
        }
        break;

      case OUCH2:
        if (value == null) {
          unsetOuch2();
        } else {
          setOuch2((AccumuloSecurityException)value);
        }
        break;

      case OUCH3:
        if (value == null) {
          unsetOuch3();
        } else {
          setOuch3((NamespaceNotFoundException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case OUCH1:
        return getOuch1();

      case OUCH2:
        return getOuch2();

      case OUCH3:
        return getOuch3();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case OUCH1:
        return isSetOuch1();
      case OUCH2:
        return isSetOuch2();
      case OUCH3:
        return isSetOuch3();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof attachNamespaceIterator_result)
        return this.equals((attachNamespaceIterator_result)that);
      return false;
    }

    public boolean equals(attachNamespaceIterator_result that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_ouch1 = true && this.isSetOuch1();
      boolean that_present_ouch1 = true && that.isSetOuch1();
      if (this_present_ouch1 || that_present_ouch1) {
        if (!(this_present_ouch1 && that_present_ouch1))
          return false;
        if (!this.ouch1.equals(that.ouch1))
          return false;
      }

      boolean this_present_ouch2 = true && this.isSetOuch2();
      boolean that_present_ouch2 = true && that.isSetOuch2();
      if (this_present_ouch2 || that_present_ouch2) {
        if (!(this_present_ouch2 && that_present_ouch2))
          return false;
        if (!this.ouch2.equals(that.ouch2))
          return false;
      }

      boolean this_present_ouch3 = true && this.isSetOuch3();
      boolean that_present_ouch3 = true && that.isSetOuch3();
      if (this_present_ouch3 || that_present_ouch3) {
        if (!(this_present_ouch3 && that_present_ouch3))
          return false;
        if (!this.ouch3.equals(that.ouch3))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
      if (isSetOuch1())
        hashCode = hashCode * 8191 + ouch1.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
      if (isSetOuch2())
        hashCode = hashCode * 8191 + ouch2.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
      if (isSetOuch3())
        hashCode = hashCode * 8191 + ouch3.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(attachNamespaceIterator_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch1()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch2()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch3()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch3, other.ouch3);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("attachNamespaceIterator_result(");
      boolean first = true;

      sb.append("ouch1:");
      if (this.ouch1 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch1);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch2:");
      if (this.ouch2 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch2);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch3:");
      if (this.ouch3 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch3);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class attachNamespaceIterator_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public attachNamespaceIterator_resultStandardScheme getScheme() {
        return new attachNamespaceIterator_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // OUCH1
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch1 = new AccumuloException();
                struct.ouch1.read(iprot);
                struct.setOuch1IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OUCH2
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch2 = new AccumuloSecurityException();
                struct.ouch2.read(iprot);
                struct.setOuch2IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // OUCH3
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch3 = new NamespaceNotFoundException();
                struct.ouch3.read(iprot);
                struct.setOuch3IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, attachNamespaceIterator_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.ouch1 != null) {
          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
          struct.ouch1.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch2 != null) {
          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
          struct.ouch2.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch3 != null) {
          oprot.writeFieldBegin(OUCH3_FIELD_DESC);
          struct.ouch3.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class attachNamespaceIterator_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public attachNamespaceIterator_resultTupleScheme getScheme() {
        return new attachNamespaceIterator_resultTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetOuch2()) {
          optionals.set(1);
        }
        if (struct.isSetOuch3()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetOuch1()) {
          struct.ouch1.write(oprot);
        }
        if (struct.isSetOuch2()) {
          struct.ouch2.write(oprot);
        }
        if (struct.isSetOuch3()) {
          struct.ouch3.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, attachNamespaceIterator_result struct) throws org.apache.thrift.TException {
        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);
          struct.setOuch1IsSet(true);
        }
        if (incoming.get(1)) {
          struct.ouch2 = new AccumuloSecurityException();
          struct.ouch2.read(iprot);
          struct.setOuch2IsSet(true);
        }
        if (incoming.get(2)) {
          struct.ouch3 = new NamespaceNotFoundException();
          struct.ouch3.read(iprot);
          struct.setOuch3IsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("removeNamespaceIterator_args");

    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField NAMESPACE_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("namespaceName", org.apache.thrift.protocol.TType.STRING, (short)2);
    private static final org.apache.thrift.protocol.TField NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("name", org.apache.thrift.protocol.TType.STRING, (short)3);
    private static final org.apache.thrift.protocol.TField SCOPES_FIELD_DESC = new org.apache.thrift.protocol.TField("scopes", org.apache.thrift.protocol.TType.SET, (short)4);

    private static final 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 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 {
      LOGIN((short)1, "login"),
      NAMESPACE_NAME((short)2, "namespaceName"),
      NAME((short)3, "name"),
      SCOPES((short)4, "scopes");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // LOGIN
            return LOGIN;
          case 2: // NAMESPACE_NAME
            return NAMESPACE_NAME;
          case 3: // NAME
            return NAME;
          case 4: // SCOPES
            return SCOPES;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.NAME, new org.apache.thrift.meta_data.FieldMetaData("name", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.SCOPES, new org.apache.thrift.meta_data.FieldMetaData("scopes", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.SetMetaData(org.apache.thrift.protocol.TType.SET, 
              new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, IteratorScope.class))));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(removeNamespaceIterator_args.class, metaDataMap);
    }

    public removeNamespaceIterator_args() {
    }

    public removeNamespaceIterator_args(
      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);
      this.namespaceName = namespaceName;
      this.name = name;
      this.scopes = scopes;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public removeNamespaceIterator_args(removeNamespaceIterator_args other) {
      if (other.isSetLogin()) {
        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
      }
      if (other.isSetNamespaceName()) {
        this.namespaceName = other.namespaceName;
      }
      if (other.isSetName()) {
        this.name = other.name;
      }
      if (other.isSetScopes()) {
        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);
        }
        this.scopes = __this__scopes;
      }
    }

    public removeNamespaceIterator_args deepCopy() {
      return new removeNamespaceIterator_args(this);
    }

    @Override
    public void clear() {
      this.login = null;
      this.namespaceName = null;
      this.name = null;
      this.scopes = null;
    }

    public byte[] getLogin() {
      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
      return login == null ? null : login.array();
    }

    public java.nio.ByteBuffer bufferForLogin() {
      return org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    public removeNamespaceIterator_args setLogin(byte[] login) {
      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
      return this;
    }

    public removeNamespaceIterator_args setLogin(java.nio.ByteBuffer login) {
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      return this;
    }

    public void unsetLogin() {
      this.login = null;
    }

    /** Returns true if field login is set (has been assigned a value) and false otherwise */
    public boolean isSetLogin() {
      return this.login != null;
    }

    public void setLoginIsSet(boolean value) {
      if (!value) {
        this.login = null;
      }
    }

    public java.lang.String getNamespaceName() {
      return this.namespaceName;
    }

    public removeNamespaceIterator_args setNamespaceName(java.lang.String namespaceName) {
      this.namespaceName = namespaceName;
      return this;
    }

    public void unsetNamespaceName() {
      this.namespaceName = null;
    }

    /** Returns true if field namespaceName is set (has been assigned a value) and false otherwise */
    public boolean isSetNamespaceName() {
      return this.namespaceName != null;
    }

    public void setNamespaceNameIsSet(boolean value) {
      if (!value) {
        this.namespaceName = null;
      }
    }

    public java.lang.String getName() {
      return this.name;
    }

    public removeNamespaceIterator_args setName(java.lang.String name) {
      this.name = name;
      return this;
    }

    public void unsetName() {
      this.name = null;
    }

    /** Returns true if field name is set (has been assigned a value) and false otherwise */
    public boolean isSetName() {
      return this.name != null;
    }

    public void setNameIsSet(boolean value) {
      if (!value) {
        this.name = null;
      }
    }

    public int getScopesSize() {
      return (this.scopes == null) ? 0 : this.scopes.size();
    }

    public java.util.Iterator<IteratorScope> getScopesIterator() {
      return (this.scopes == null) ? null : this.scopes.iterator();
    }

    public void addToScopes(IteratorScope elem) {
      if (this.scopes == null) {
        this.scopes = new java.util.HashSet<IteratorScope>();
      }
      this.scopes.add(elem);
    }

    public java.util.Set<IteratorScope> getScopes() {
      return this.scopes;
    }

    public removeNamespaceIterator_args setScopes(java.util.Set<IteratorScope> scopes) {
      this.scopes = scopes;
      return this;
    }

    public void unsetScopes() {
      this.scopes = null;
    }

    /** Returns true if field scopes is set (has been assigned a value) and false otherwise */
    public boolean isSetScopes() {
      return this.scopes != null;
    }

    public void setScopesIsSet(boolean value) {
      if (!value) {
        this.scopes = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case LOGIN:
        if (value == null) {
          unsetLogin();
        } else {
          if (value instanceof byte[]) {
            setLogin((byte[])value);
          } else {
            setLogin((java.nio.ByteBuffer)value);
          }
        }
        break;

      case NAMESPACE_NAME:
        if (value == null) {
          unsetNamespaceName();
        } else {
          setNamespaceName((java.lang.String)value);
        }
        break;

      case NAME:
        if (value == null) {
          unsetName();
        } else {
          setName((java.lang.String)value);
        }
        break;

      case SCOPES:
        if (value == null) {
          unsetScopes();
        } else {
          setScopes((java.util.Set<IteratorScope>)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case LOGIN:
        return getLogin();

      case NAMESPACE_NAME:
        return getNamespaceName();

      case NAME:
        return getName();

      case SCOPES:
        return getScopes();

      }
      throw new 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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case LOGIN:
        return isSetLogin();
      case NAMESPACE_NAME:
        return isSetNamespaceName();
      case NAME:
        return isSetName();
      case SCOPES:
        return isSetScopes();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof removeNamespaceIterator_args)
        return this.equals((removeNamespaceIterator_args)that);
      return false;
    }

    public boolean equals(removeNamespaceIterator_args that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_login = true && this.isSetLogin();
      boolean that_present_login = true && that.isSetLogin();
      if (this_present_login || that_present_login) {
        if (!(this_present_login && that_present_login))
          return false;
        if (!this.login.equals(that.login))
          return false;
      }

      boolean this_present_namespaceName = true && this.isSetNamespaceName();
      boolean that_present_namespaceName = true && that.isSetNamespaceName();
      if (this_present_namespaceName || that_present_namespaceName) {
        if (!(this_present_namespaceName && that_present_namespaceName))
          return false;
        if (!this.namespaceName.equals(that.namespaceName))
          return false;
      }

      boolean this_present_name = true && this.isSetName();
      boolean that_present_name = true && that.isSetName();
      if (this_present_name || that_present_name) {
        if (!(this_present_name && that_present_name))
          return false;
        if (!this.name.equals(that.name))
          return false;
      }

      boolean this_present_scopes = true && this.isSetScopes();
      boolean that_present_scopes = true && that.isSetScopes();
      if (this_present_scopes || that_present_scopes) {
        if (!(this_present_scopes && that_present_scopes))
          return false;
        if (!this.scopes.equals(that.scopes))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
      if (isSetLogin())
        hashCode = hashCode * 8191 + login.hashCode();

      hashCode = hashCode * 8191 + ((isSetNamespaceName()) ? 131071 : 524287);
      if (isSetNamespaceName())
        hashCode = hashCode * 8191 + namespaceName.hashCode();

      hashCode = hashCode * 8191 + ((isSetName()) ? 131071 : 524287);
      if (isSetName())
        hashCode = hashCode * 8191 + name.hashCode();

      hashCode = hashCode * 8191 + ((isSetScopes()) ? 131071 : 524287);
      if (isSetScopes())
        hashCode = hashCode * 8191 + scopes.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(removeNamespaceIterator_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLogin()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetNamespaceName()).compareTo(other.isSetNamespaceName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetNamespaceName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.namespaceName, other.namespaceName);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetName()).compareTo(other.isSetName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.name, other.name);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetScopes()).compareTo(other.isSetScopes());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetScopes()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.scopes, other.scopes);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("removeNamespaceIterator_args(");
      boolean first = true;

      sb.append("login:");
      if (this.login == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.login, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("namespaceName:");
      if (this.namespaceName == null) {
        sb.append("null");
      } else {
        sb.append(this.namespaceName);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("name:");
      if (this.name == null) {
        sb.append("null");
      } else {
        sb.append(this.name);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("scopes:");
      if (this.scopes == null) {
        sb.append("null");
      } else {
        sb.append(this.scopes);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class removeNamespaceIterator_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public removeNamespaceIterator_argsStandardScheme getScheme() {
        return new removeNamespaceIterator_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // LOGIN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.login = iprot.readBinary();
                struct.setLoginIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // NAMESPACE_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.namespaceName = iprot.readString();
                struct.setNamespaceNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.name = iprot.readString();
                struct.setNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // SCOPES
              if (schemeField.type == org.apache.thrift.protocol.TType.SET) {
                {
                  org.apache.thrift.protocol.TSet _set534 = iprot.readSetBegin();
                  struct.scopes = new java.util.HashSet<IteratorScope>(2*_set534.size);
                  IteratorScope _elem535;
                  for (int _i536 = 0; _i536 < _set534.size; ++_i536)
                  {
                    _elem535 = org.apache.accumulo.proxy.thrift.IteratorScope.findByValue(iprot.readI32());
                    struct.scopes.add(_elem535);
                  }
                  iprot.readSetEnd();
                }
                struct.setScopesIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, removeNamespaceIterator_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.login != null) {
          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
          oprot.writeBinary(struct.login);
          oprot.writeFieldEnd();
        }
        if (struct.namespaceName != null) {
          oprot.writeFieldBegin(NAMESPACE_NAME_FIELD_DESC);
          oprot.writeString(struct.namespaceName);
          oprot.writeFieldEnd();
        }
        if (struct.name != null) {
          oprot.writeFieldBegin(NAME_FIELD_DESC);
          oprot.writeString(struct.name);
          oprot.writeFieldEnd();
        }
        if (struct.scopes != null) {
          oprot.writeFieldBegin(SCOPES_FIELD_DESC);
          {
            oprot.writeSetBegin(new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.I32, struct.scopes.size()));
            for (IteratorScope _iter537 : struct.scopes)
            {
              oprot.writeI32(_iter537.getValue());
            }
            oprot.writeSetEnd();
          }
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class removeNamespaceIterator_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public removeNamespaceIterator_argsTupleScheme getScheme() {
        return new removeNamespaceIterator_argsTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetNamespaceName()) {
          optionals.set(1);
        }
        if (struct.isSetName()) {
          optionals.set(2);
        }
        if (struct.isSetScopes()) {
          optionals.set(3);
        }
        oprot.writeBitSet(optionals, 4);
        if (struct.isSetLogin()) {
          oprot.writeBinary(struct.login);
        }
        if (struct.isSetNamespaceName()) {
          oprot.writeString(struct.namespaceName);
        }
        if (struct.isSetName()) {
          oprot.writeString(struct.name);
        }
        if (struct.isSetScopes()) {
          {
            oprot.writeI32(struct.scopes.size());
            for (IteratorScope _iter538 : struct.scopes)
            {
              oprot.writeI32(_iter538.getValue());
            }
          }
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, removeNamespaceIterator_args struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.namespaceName = iprot.readString();
          struct.setNamespaceNameIsSet(true);
        }
        if (incoming.get(2)) {
          struct.name = iprot.readString();
          struct.setNameIsSet(true);
        }
        if (incoming.get(3)) {
          {
            org.apache.thrift.protocol.TSet _set539 = new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.I32, iprot.readI32());
            struct.scopes = new java.util.HashSet<IteratorScope>(2*_set539.size);
            IteratorScope _elem540;
            for (int _i541 = 0; _i541 < _set539.size; ++_i541)
            {
              _elem540 = org.apache.accumulo.proxy.thrift.IteratorScope.findByValue(iprot.readI32());
              struct.scopes.add(_elem540);
            }
          }
          struct.setScopesIsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("removeNamespaceIterator_result");

    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField OUCH3_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch3", org.apache.thrift.protocol.TType.STRUCT, (short)3);

    private static final 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
    public NamespaceNotFoundException ouch3; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      OUCH1((short)1, "ouch1"),
      OUCH2((short)2, "ouch2"),
      OUCH3((short)3, "ouch3");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // OUCH1
            return OUCH1;
          case 2: // OUCH2
            return OUCH2;
          case 3: // OUCH3
            return OUCH3;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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.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.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);
    }

    public removeNamespaceIterator_result() {
    }

    public removeNamespaceIterator_result(
      AccumuloException ouch1,
      AccumuloSecurityException ouch2,
      NamespaceNotFoundException ouch3)
    {
      this();
      this.ouch1 = ouch1;
      this.ouch2 = ouch2;
      this.ouch3 = ouch3;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public removeNamespaceIterator_result(removeNamespaceIterator_result other) {
      if (other.isSetOuch1()) {
        this.ouch1 = new AccumuloException(other.ouch1);
      }
      if (other.isSetOuch2()) {
        this.ouch2 = new AccumuloSecurityException(other.ouch2);
      }
      if (other.isSetOuch3()) {
        this.ouch3 = new NamespaceNotFoundException(other.ouch3);
      }
    }

    public removeNamespaceIterator_result deepCopy() {
      return new removeNamespaceIterator_result(this);
    }

    @Override
    public void clear() {
      this.ouch1 = null;
      this.ouch2 = null;
      this.ouch3 = null;
    }

    public AccumuloException getOuch1() {
      return this.ouch1;
    }

    public removeNamespaceIterator_result setOuch1(AccumuloException ouch1) {
      this.ouch1 = ouch1;
      return this;
    }

    public void unsetOuch1() {
      this.ouch1 = null;
    }

    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch1() {
      return this.ouch1 != null;
    }

    public void setOuch1IsSet(boolean value) {
      if (!value) {
        this.ouch1 = null;
      }
    }

    public AccumuloSecurityException getOuch2() {
      return this.ouch2;
    }

    public removeNamespaceIterator_result setOuch2(AccumuloSecurityException ouch2) {
      this.ouch2 = ouch2;
      return this;
    }

    public void unsetOuch2() {
      this.ouch2 = null;
    }

    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch2() {
      return this.ouch2 != null;
    }

    public void setOuch2IsSet(boolean value) {
      if (!value) {
        this.ouch2 = null;
      }
    }

    public NamespaceNotFoundException getOuch3() {
      return this.ouch3;
    }

    public removeNamespaceIterator_result setOuch3(NamespaceNotFoundException ouch3) {
      this.ouch3 = ouch3;
      return this;
    }

    public void unsetOuch3() {
      this.ouch3 = null;
    }

    /** Returns true if field ouch3 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch3() {
      return this.ouch3 != null;
    }

    public void setOuch3IsSet(boolean value) {
      if (!value) {
        this.ouch3 = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case OUCH1:
        if (value == null) {
          unsetOuch1();
        } else {
          setOuch1((AccumuloException)value);
        }
        break;

      case OUCH2:
        if (value == null) {
          unsetOuch2();
        } else {
          setOuch2((AccumuloSecurityException)value);
        }
        break;

      case OUCH3:
        if (value == null) {
          unsetOuch3();
        } else {
          setOuch3((NamespaceNotFoundException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case OUCH1:
        return getOuch1();

      case OUCH2:
        return getOuch2();

      case OUCH3:
        return getOuch3();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case OUCH1:
        return isSetOuch1();
      case OUCH2:
        return isSetOuch2();
      case OUCH3:
        return isSetOuch3();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof removeNamespaceIterator_result)
        return this.equals((removeNamespaceIterator_result)that);
      return false;
    }

    public boolean equals(removeNamespaceIterator_result that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_ouch1 = true && this.isSetOuch1();
      boolean that_present_ouch1 = true && that.isSetOuch1();
      if (this_present_ouch1 || that_present_ouch1) {
        if (!(this_present_ouch1 && that_present_ouch1))
          return false;
        if (!this.ouch1.equals(that.ouch1))
          return false;
      }

      boolean this_present_ouch2 = true && this.isSetOuch2();
      boolean that_present_ouch2 = true && that.isSetOuch2();
      if (this_present_ouch2 || that_present_ouch2) {
        if (!(this_present_ouch2 && that_present_ouch2))
          return false;
        if (!this.ouch2.equals(that.ouch2))
          return false;
      }

      boolean this_present_ouch3 = true && this.isSetOuch3();
      boolean that_present_ouch3 = true && that.isSetOuch3();
      if (this_present_ouch3 || that_present_ouch3) {
        if (!(this_present_ouch3 && that_present_ouch3))
          return false;
        if (!this.ouch3.equals(that.ouch3))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
      if (isSetOuch1())
        hashCode = hashCode * 8191 + ouch1.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
      if (isSetOuch2())
        hashCode = hashCode * 8191 + ouch2.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
      if (isSetOuch3())
        hashCode = hashCode * 8191 + ouch3.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(removeNamespaceIterator_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch1()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch2()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch3()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch3, other.ouch3);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("removeNamespaceIterator_result(");
      boolean first = true;

      sb.append("ouch1:");
      if (this.ouch1 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch1);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch2:");
      if (this.ouch2 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch2);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch3:");
      if (this.ouch3 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch3);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class removeNamespaceIterator_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public removeNamespaceIterator_resultStandardScheme getScheme() {
        return new removeNamespaceIterator_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // OUCH1
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch1 = new AccumuloException();
                struct.ouch1.read(iprot);
                struct.setOuch1IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OUCH2
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch2 = new AccumuloSecurityException();
                struct.ouch2.read(iprot);
                struct.setOuch2IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // OUCH3
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch3 = new NamespaceNotFoundException();
                struct.ouch3.read(iprot);
                struct.setOuch3IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, removeNamespaceIterator_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.ouch1 != null) {
          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
          struct.ouch1.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch2 != null) {
          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
          struct.ouch2.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch3 != null) {
          oprot.writeFieldBegin(OUCH3_FIELD_DESC);
          struct.ouch3.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class removeNamespaceIterator_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public removeNamespaceIterator_resultTupleScheme getScheme() {
        return new removeNamespaceIterator_resultTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetOuch2()) {
          optionals.set(1);
        }
        if (struct.isSetOuch3()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetOuch1()) {
          struct.ouch1.write(oprot);
        }
        if (struct.isSetOuch2()) {
          struct.ouch2.write(oprot);
        }
        if (struct.isSetOuch3()) {
          struct.ouch3.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, removeNamespaceIterator_result struct) throws org.apache.thrift.TException {
        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);
          struct.setOuch1IsSet(true);
        }
        if (incoming.get(1)) {
          struct.ouch2 = new AccumuloSecurityException();
          struct.ouch2.read(iprot);
          struct.setOuch2IsSet(true);
        }
        if (incoming.get(2)) {
          struct.ouch3 = new NamespaceNotFoundException();
          struct.ouch3.read(iprot);
          struct.setOuch3IsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getNamespaceIteratorSetting_args");

    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField NAMESPACE_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("namespaceName", org.apache.thrift.protocol.TType.STRING, (short)2);
    private static final org.apache.thrift.protocol.TField NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("name", org.apache.thrift.protocol.TType.STRING, (short)3);
    private static final org.apache.thrift.protocol.TField SCOPE_FIELD_DESC = new org.apache.thrift.protocol.TField("scope", org.apache.thrift.protocol.TType.I32, (short)4);

    private static final 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 java.nio.ByteBuffer login; // required
    public java.lang.String namespaceName; // required
    public java.lang.String name; // required
    /**
     * 
     * @see IteratorScope
     */
    public IteratorScope scope; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      LOGIN((short)1, "login"),
      NAMESPACE_NAME((short)2, "namespaceName"),
      NAME((short)3, "name"),
      /**
       * 
       * @see IteratorScope
       */
      SCOPE((short)4, "scope");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // LOGIN
            return LOGIN;
          case 2: // NAMESPACE_NAME
            return NAMESPACE_NAME;
          case 3: // NAME
            return NAME;
          case 4: // SCOPE
            return SCOPE;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.NAME, new org.apache.thrift.meta_data.FieldMetaData("name", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.SCOPE, new org.apache.thrift.meta_data.FieldMetaData("scope", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, IteratorScope.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getNamespaceIteratorSetting_args.class, metaDataMap);
    }

    public getNamespaceIteratorSetting_args() {
    }

    public getNamespaceIteratorSetting_args(
      java.nio.ByteBuffer login,
      java.lang.String namespaceName,
      java.lang.String name,
      IteratorScope scope)
    {
      this();
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      this.namespaceName = namespaceName;
      this.name = name;
      this.scope = scope;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getNamespaceIteratorSetting_args(getNamespaceIteratorSetting_args other) {
      if (other.isSetLogin()) {
        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
      }
      if (other.isSetNamespaceName()) {
        this.namespaceName = other.namespaceName;
      }
      if (other.isSetName()) {
        this.name = other.name;
      }
      if (other.isSetScope()) {
        this.scope = other.scope;
      }
    }

    public getNamespaceIteratorSetting_args deepCopy() {
      return new getNamespaceIteratorSetting_args(this);
    }

    @Override
    public void clear() {
      this.login = null;
      this.namespaceName = null;
      this.name = null;
      this.scope = null;
    }

    public byte[] getLogin() {
      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
      return login == null ? null : login.array();
    }

    public java.nio.ByteBuffer bufferForLogin() {
      return org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    public getNamespaceIteratorSetting_args setLogin(byte[] login) {
      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
      return this;
    }

    public getNamespaceIteratorSetting_args setLogin(java.nio.ByteBuffer login) {
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      return this;
    }

    public void unsetLogin() {
      this.login = null;
    }

    /** Returns true if field login is set (has been assigned a value) and false otherwise */
    public boolean isSetLogin() {
      return this.login != null;
    }

    public void setLoginIsSet(boolean value) {
      if (!value) {
        this.login = null;
      }
    }

    public java.lang.String getNamespaceName() {
      return this.namespaceName;
    }

    public getNamespaceIteratorSetting_args setNamespaceName(java.lang.String namespaceName) {
      this.namespaceName = namespaceName;
      return this;
    }

    public void unsetNamespaceName() {
      this.namespaceName = null;
    }

    /** Returns true if field namespaceName is set (has been assigned a value) and false otherwise */
    public boolean isSetNamespaceName() {
      return this.namespaceName != null;
    }

    public void setNamespaceNameIsSet(boolean value) {
      if (!value) {
        this.namespaceName = null;
      }
    }

    public java.lang.String getName() {
      return this.name;
    }

    public getNamespaceIteratorSetting_args setName(java.lang.String name) {
      this.name = name;
      return this;
    }

    public void unsetName() {
      this.name = null;
    }

    /** Returns true if field name is set (has been assigned a value) and false otherwise */
    public boolean isSetName() {
      return this.name != null;
    }

    public void setNameIsSet(boolean value) {
      if (!value) {
        this.name = null;
      }
    }

    /**
     * 
     * @see IteratorScope
     */
    public IteratorScope getScope() {
      return this.scope;
    }

    /**
     * 
     * @see IteratorScope
     */
    public getNamespaceIteratorSetting_args setScope(IteratorScope scope) {
      this.scope = scope;
      return this;
    }

    public void unsetScope() {
      this.scope = null;
    }

    /** Returns true if field scope is set (has been assigned a value) and false otherwise */
    public boolean isSetScope() {
      return this.scope != null;
    }

    public void setScopeIsSet(boolean value) {
      if (!value) {
        this.scope = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case LOGIN:
        if (value == null) {
          unsetLogin();
        } else {
          if (value instanceof byte[]) {
            setLogin((byte[])value);
          } else {
            setLogin((java.nio.ByteBuffer)value);
          }
        }
        break;

      case NAMESPACE_NAME:
        if (value == null) {
          unsetNamespaceName();
        } else {
          setNamespaceName((java.lang.String)value);
        }
        break;

      case NAME:
        if (value == null) {
          unsetName();
        } else {
          setName((java.lang.String)value);
        }
        break;

      case SCOPE:
        if (value == null) {
          unsetScope();
        } else {
          setScope((IteratorScope)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case LOGIN:
        return getLogin();

      case NAMESPACE_NAME:
        return getNamespaceName();

      case NAME:
        return getName();

      case SCOPE:
        return getScope();

      }
      throw new 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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case LOGIN:
        return isSetLogin();
      case NAMESPACE_NAME:
        return isSetNamespaceName();
      case NAME:
        return isSetName();
      case SCOPE:
        return isSetScope();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof getNamespaceIteratorSetting_args)
        return this.equals((getNamespaceIteratorSetting_args)that);
      return false;
    }

    public boolean equals(getNamespaceIteratorSetting_args that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_login = true && this.isSetLogin();
      boolean that_present_login = true && that.isSetLogin();
      if (this_present_login || that_present_login) {
        if (!(this_present_login && that_present_login))
          return false;
        if (!this.login.equals(that.login))
          return false;
      }

      boolean this_present_namespaceName = true && this.isSetNamespaceName();
      boolean that_present_namespaceName = true && that.isSetNamespaceName();
      if (this_present_namespaceName || that_present_namespaceName) {
        if (!(this_present_namespaceName && that_present_namespaceName))
          return false;
        if (!this.namespaceName.equals(that.namespaceName))
          return false;
      }

      boolean this_present_name = true && this.isSetName();
      boolean that_present_name = true && that.isSetName();
      if (this_present_name || that_present_name) {
        if (!(this_present_name && that_present_name))
          return false;
        if (!this.name.equals(that.name))
          return false;
      }

      boolean this_present_scope = true && this.isSetScope();
      boolean that_present_scope = true && that.isSetScope();
      if (this_present_scope || that_present_scope) {
        if (!(this_present_scope && that_present_scope))
          return false;
        if (!this.scope.equals(that.scope))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
      if (isSetLogin())
        hashCode = hashCode * 8191 + login.hashCode();

      hashCode = hashCode * 8191 + ((isSetNamespaceName()) ? 131071 : 524287);
      if (isSetNamespaceName())
        hashCode = hashCode * 8191 + namespaceName.hashCode();

      hashCode = hashCode * 8191 + ((isSetName()) ? 131071 : 524287);
      if (isSetName())
        hashCode = hashCode * 8191 + name.hashCode();

      hashCode = hashCode * 8191 + ((isSetScope()) ? 131071 : 524287);
      if (isSetScope())
        hashCode = hashCode * 8191 + scope.getValue();

      return hashCode;
    }

    @Override
    public int compareTo(getNamespaceIteratorSetting_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLogin()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetNamespaceName()).compareTo(other.isSetNamespaceName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetNamespaceName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.namespaceName, other.namespaceName);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetName()).compareTo(other.isSetName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.name, other.name);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetScope()).compareTo(other.isSetScope());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetScope()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.scope, other.scope);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("getNamespaceIteratorSetting_args(");
      boolean first = true;

      sb.append("login:");
      if (this.login == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.login, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("namespaceName:");
      if (this.namespaceName == null) {
        sb.append("null");
      } else {
        sb.append(this.namespaceName);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("name:");
      if (this.name == null) {
        sb.append("null");
      } else {
        sb.append(this.name);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("scope:");
      if (this.scope == null) {
        sb.append("null");
      } else {
        sb.append(this.scope);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class getNamespaceIteratorSetting_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getNamespaceIteratorSetting_argsStandardScheme getScheme() {
        return new getNamespaceIteratorSetting_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // LOGIN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.login = iprot.readBinary();
                struct.setLoginIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // NAMESPACE_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.namespaceName = iprot.readString();
                struct.setNamespaceNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.name = iprot.readString();
                struct.setNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // SCOPE
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.scope = org.apache.accumulo.proxy.thrift.IteratorScope.findByValue(iprot.readI32());
                struct.setScopeIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getNamespaceIteratorSetting_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.login != null) {
          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
          oprot.writeBinary(struct.login);
          oprot.writeFieldEnd();
        }
        if (struct.namespaceName != null) {
          oprot.writeFieldBegin(NAMESPACE_NAME_FIELD_DESC);
          oprot.writeString(struct.namespaceName);
          oprot.writeFieldEnd();
        }
        if (struct.name != null) {
          oprot.writeFieldBegin(NAME_FIELD_DESC);
          oprot.writeString(struct.name);
          oprot.writeFieldEnd();
        }
        if (struct.scope != null) {
          oprot.writeFieldBegin(SCOPE_FIELD_DESC);
          oprot.writeI32(struct.scope.getValue());
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getNamespaceIteratorSetting_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getNamespaceIteratorSetting_argsTupleScheme getScheme() {
        return new getNamespaceIteratorSetting_argsTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetNamespaceName()) {
          optionals.set(1);
        }
        if (struct.isSetName()) {
          optionals.set(2);
        }
        if (struct.isSetScope()) {
          optionals.set(3);
        }
        oprot.writeBitSet(optionals, 4);
        if (struct.isSetLogin()) {
          oprot.writeBinary(struct.login);
        }
        if (struct.isSetNamespaceName()) {
          oprot.writeString(struct.namespaceName);
        }
        if (struct.isSetName()) {
          oprot.writeString(struct.name);
        }
        if (struct.isSetScope()) {
          oprot.writeI32(struct.scope.getValue());
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getNamespaceIteratorSetting_args struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.namespaceName = iprot.readString();
          struct.setNamespaceNameIsSet(true);
        }
        if (incoming.get(2)) {
          struct.name = iprot.readString();
          struct.setNameIsSet(true);
        }
        if (incoming.get(3)) {
          struct.scope = org.apache.accumulo.proxy.thrift.IteratorScope.findByValue(iprot.readI32());
          struct.setScopeIsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getNamespaceIteratorSetting_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.STRUCT, (short)0);
    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField OUCH3_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch3", org.apache.thrift.protocol.TType.STRUCT, (short)3);

    private static final 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
    public AccumuloSecurityException ouch2; // required
    public NamespaceNotFoundException ouch3; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      OUCH1((short)1, "ouch1"),
      OUCH2((short)2, "ouch2"),
      OUCH3((short)3, "ouch3");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // OUCH1
            return OUCH1;
          case 2: // OUCH2
            return OUCH2;
          case 3: // OUCH3
            return OUCH3;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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.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.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);
    }

    public getNamespaceIteratorSetting_result() {
    }

    public getNamespaceIteratorSetting_result(
      IteratorSetting success,
      AccumuloException ouch1,
      AccumuloSecurityException ouch2,
      NamespaceNotFoundException ouch3)
    {
      this();
      this.success = success;
      this.ouch1 = ouch1;
      this.ouch2 = ouch2;
      this.ouch3 = ouch3;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getNamespaceIteratorSetting_result(getNamespaceIteratorSetting_result other) {
      if (other.isSetSuccess()) {
        this.success = new IteratorSetting(other.success);
      }
      if (other.isSetOuch1()) {
        this.ouch1 = new AccumuloException(other.ouch1);
      }
      if (other.isSetOuch2()) {
        this.ouch2 = new AccumuloSecurityException(other.ouch2);
      }
      if (other.isSetOuch3()) {
        this.ouch3 = new NamespaceNotFoundException(other.ouch3);
      }
    }

    public getNamespaceIteratorSetting_result deepCopy() {
      return new getNamespaceIteratorSetting_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ouch1 = null;
      this.ouch2 = null;
      this.ouch3 = null;
    }

    public IteratorSetting getSuccess() {
      return this.success;
    }

    public getNamespaceIteratorSetting_result setSuccess(IteratorSetting success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return this.success != null;
    }

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public AccumuloException getOuch1() {
      return this.ouch1;
    }

    public getNamespaceIteratorSetting_result setOuch1(AccumuloException ouch1) {
      this.ouch1 = ouch1;
      return this;
    }

    public void unsetOuch1() {
      this.ouch1 = null;
    }

    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch1() {
      return this.ouch1 != null;
    }

    public void setOuch1IsSet(boolean value) {
      if (!value) {
        this.ouch1 = null;
      }
    }

    public AccumuloSecurityException getOuch2() {
      return this.ouch2;
    }

    public getNamespaceIteratorSetting_result setOuch2(AccumuloSecurityException ouch2) {
      this.ouch2 = ouch2;
      return this;
    }

    public void unsetOuch2() {
      this.ouch2 = null;
    }

    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch2() {
      return this.ouch2 != null;
    }

    public void setOuch2IsSet(boolean value) {
      if (!value) {
        this.ouch2 = null;
      }
    }

    public NamespaceNotFoundException getOuch3() {
      return this.ouch3;
    }

    public getNamespaceIteratorSetting_result setOuch3(NamespaceNotFoundException ouch3) {
      this.ouch3 = ouch3;
      return this;
    }

    public void unsetOuch3() {
      this.ouch3 = null;
    }

    /** Returns true if field ouch3 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch3() {
      return this.ouch3 != null;
    }

    public void setOuch3IsSet(boolean value) {
      if (!value) {
        this.ouch3 = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((IteratorSetting)value);
        }
        break;

      case OUCH1:
        if (value == null) {
          unsetOuch1();
        } else {
          setOuch1((AccumuloException)value);
        }
        break;

      case OUCH2:
        if (value == null) {
          unsetOuch2();
        } else {
          setOuch2((AccumuloSecurityException)value);
        }
        break;

      case OUCH3:
        if (value == null) {
          unsetOuch3();
        } else {
          setOuch3((NamespaceNotFoundException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case OUCH1:
        return getOuch1();

      case OUCH2:
        return getOuch2();

      case OUCH3:
        return getOuch3();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case OUCH1:
        return isSetOuch1();
      case OUCH2:
        return isSetOuch2();
      case OUCH3:
        return isSetOuch3();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof getNamespaceIteratorSetting_result)
        return this.equals((getNamespaceIteratorSetting_result)that);
      return false;
    }

    public boolean equals(getNamespaceIteratorSetting_result that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ouch1 = true && this.isSetOuch1();
      boolean that_present_ouch1 = true && that.isSetOuch1();
      if (this_present_ouch1 || that_present_ouch1) {
        if (!(this_present_ouch1 && that_present_ouch1))
          return false;
        if (!this.ouch1.equals(that.ouch1))
          return false;
      }

      boolean this_present_ouch2 = true && this.isSetOuch2();
      boolean that_present_ouch2 = true && that.isSetOuch2();
      if (this_present_ouch2 || that_present_ouch2) {
        if (!(this_present_ouch2 && that_present_ouch2))
          return false;
        if (!this.ouch2.equals(that.ouch2))
          return false;
      }

      boolean this_present_ouch3 = true && this.isSetOuch3();
      boolean that_present_ouch3 = true && that.isSetOuch3();
      if (this_present_ouch3 || that_present_ouch3) {
        if (!(this_present_ouch3 && that_present_ouch3))
          return false;
        if (!this.ouch3.equals(that.ouch3))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
      if (isSetSuccess())
        hashCode = hashCode * 8191 + success.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
      if (isSetOuch1())
        hashCode = hashCode * 8191 + ouch1.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
      if (isSetOuch2())
        hashCode = hashCode * 8191 + ouch2.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
      if (isSetOuch3())
        hashCode = hashCode * 8191 + ouch3.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(getNamespaceIteratorSetting_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch1()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch2()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch3()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch3, other.ouch3);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("getNamespaceIteratorSetting_result(");
      boolean first = true;

      sb.append("success:");
      if (this.success == null) {
        sb.append("null");
      } else {
        sb.append(this.success);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch1:");
      if (this.ouch1 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch1);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch2:");
      if (this.ouch2 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch2);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch3:");
      if (this.ouch3 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch3);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
      if (success != null) {
        success.validate();
      }
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class getNamespaceIteratorSetting_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getNamespaceIteratorSetting_resultStandardScheme getScheme() {
        return new getNamespaceIteratorSetting_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.success = new IteratorSetting();
                struct.success.read(iprot);
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // OUCH1
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch1 = new AccumuloException();
                struct.ouch1.read(iprot);
                struct.setOuch1IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OUCH2
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch2 = new AccumuloSecurityException();
                struct.ouch2.read(iprot);
                struct.setOuch2IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // OUCH3
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch3 = new NamespaceNotFoundException();
                struct.ouch3.read(iprot);
                struct.setOuch3IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getNamespaceIteratorSetting_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          struct.success.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch1 != null) {
          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
          struct.ouch1.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch2 != null) {
          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
          struct.ouch2.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch3 != null) {
          oprot.writeFieldBegin(OUCH3_FIELD_DESC);
          struct.ouch3.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getNamespaceIteratorSetting_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getNamespaceIteratorSetting_resultTupleScheme getScheme() {
        return new getNamespaceIteratorSetting_resultTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetOuch1()) {
          optionals.set(1);
        }
        if (struct.isSetOuch2()) {
          optionals.set(2);
        }
        if (struct.isSetOuch3()) {
          optionals.set(3);
        }
        oprot.writeBitSet(optionals, 4);
        if (struct.isSetSuccess()) {
          struct.success.write(oprot);
        }
        if (struct.isSetOuch1()) {
          struct.ouch1.write(oprot);
        }
        if (struct.isSetOuch2()) {
          struct.ouch2.write(oprot);
        }
        if (struct.isSetOuch3()) {
          struct.ouch3.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getNamespaceIteratorSetting_result struct) throws org.apache.thrift.TException {
        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);
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ouch1 = new AccumuloException();
          struct.ouch1.read(iprot);
          struct.setOuch1IsSet(true);
        }
        if (incoming.get(2)) {
          struct.ouch2 = new AccumuloSecurityException();
          struct.ouch2.read(iprot);
          struct.setOuch2IsSet(true);
        }
        if (incoming.get(3)) {
          struct.ouch3 = new NamespaceNotFoundException();
          struct.ouch3.read(iprot);
          struct.setOuch3IsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("listNamespaceIterators_args");

    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField NAMESPACE_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("namespaceName", org.apache.thrift.protocol.TType.STRING, (short)2);

    private static final 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 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 java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // LOGIN
            return LOGIN;
          case 2: // NAMESPACE_NAME
            return NAMESPACE_NAME;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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 = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(listNamespaceIterators_args.class, metaDataMap);
    }

    public listNamespaceIterators_args() {
    }

    public listNamespaceIterators_args(
      java.nio.ByteBuffer login,
      java.lang.String namespaceName)
    {
      this();
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      this.namespaceName = namespaceName;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public listNamespaceIterators_args(listNamespaceIterators_args other) {
      if (other.isSetLogin()) {
        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
      }
      if (other.isSetNamespaceName()) {
        this.namespaceName = other.namespaceName;
      }
    }

    public listNamespaceIterators_args deepCopy() {
      return new listNamespaceIterators_args(this);
    }

    @Override
    public void clear() {
      this.login = null;
      this.namespaceName = null;
    }

    public byte[] getLogin() {
      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
      return login == null ? null : login.array();
    }

    public java.nio.ByteBuffer bufferForLogin() {
      return org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    public listNamespaceIterators_args setLogin(byte[] login) {
      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
      return this;
    }

    public listNamespaceIterators_args setLogin(java.nio.ByteBuffer login) {
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      return this;
    }

    public void unsetLogin() {
      this.login = null;
    }

    /** Returns true if field login is set (has been assigned a value) and false otherwise */
    public boolean isSetLogin() {
      return this.login != null;
    }

    public void setLoginIsSet(boolean value) {
      if (!value) {
        this.login = null;
      }
    }

    public java.lang.String getNamespaceName() {
      return this.namespaceName;
    }

    public listNamespaceIterators_args setNamespaceName(java.lang.String namespaceName) {
      this.namespaceName = namespaceName;
      return this;
    }

    public void unsetNamespaceName() {
      this.namespaceName = null;
    }

    /** Returns true if field namespaceName is set (has been assigned a value) and false otherwise */
    public boolean isSetNamespaceName() {
      return this.namespaceName != null;
    }

    public void setNamespaceNameIsSet(boolean value) {
      if (!value) {
        this.namespaceName = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case LOGIN:
        if (value == null) {
          unsetLogin();
        } else {
          if (value instanceof byte[]) {
            setLogin((byte[])value);
          } else {
            setLogin((java.nio.ByteBuffer)value);
          }
        }
        break;

      case NAMESPACE_NAME:
        if (value == null) {
          unsetNamespaceName();
        } else {
          setNamespaceName((java.lang.String)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case LOGIN:
        return getLogin();

      case NAMESPACE_NAME:
        return getNamespaceName();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case LOGIN:
        return isSetLogin();
      case NAMESPACE_NAME:
        return isSetNamespaceName();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof listNamespaceIterators_args)
        return this.equals((listNamespaceIterators_args)that);
      return false;
    }

    public boolean equals(listNamespaceIterators_args that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_login = true && this.isSetLogin();
      boolean that_present_login = true && that.isSetLogin();
      if (this_present_login || that_present_login) {
        if (!(this_present_login && that_present_login))
          return false;
        if (!this.login.equals(that.login))
          return false;
      }

      boolean this_present_namespaceName = true && this.isSetNamespaceName();
      boolean that_present_namespaceName = true && that.isSetNamespaceName();
      if (this_present_namespaceName || that_present_namespaceName) {
        if (!(this_present_namespaceName && that_present_namespaceName))
          return false;
        if (!this.namespaceName.equals(that.namespaceName))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
      if (isSetLogin())
        hashCode = hashCode * 8191 + login.hashCode();

      hashCode = hashCode * 8191 + ((isSetNamespaceName()) ? 131071 : 524287);
      if (isSetNamespaceName())
        hashCode = hashCode * 8191 + namespaceName.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(listNamespaceIterators_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLogin()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetNamespaceName()).compareTo(other.isSetNamespaceName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetNamespaceName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.namespaceName, other.namespaceName);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("listNamespaceIterators_args(");
      boolean first = true;

      sb.append("login:");
      if (this.login == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.login, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("namespaceName:");
      if (this.namespaceName == null) {
        sb.append("null");
      } else {
        sb.append(this.namespaceName);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class listNamespaceIterators_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public listNamespaceIterators_argsStandardScheme getScheme() {
        return new listNamespaceIterators_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // LOGIN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.login = iprot.readBinary();
                struct.setLoginIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // NAMESPACE_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.namespaceName = iprot.readString();
                struct.setNamespaceNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, listNamespaceIterators_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.login != null) {
          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
          oprot.writeBinary(struct.login);
          oprot.writeFieldEnd();
        }
        if (struct.namespaceName != null) {
          oprot.writeFieldBegin(NAMESPACE_NAME_FIELD_DESC);
          oprot.writeString(struct.namespaceName);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class listNamespaceIterators_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public listNamespaceIterators_argsTupleScheme getScheme() {
        return new listNamespaceIterators_argsTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetNamespaceName()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetLogin()) {
          oprot.writeBinary(struct.login);
        }
        if (struct.isSetNamespaceName()) {
          oprot.writeString(struct.namespaceName);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, listNamespaceIterators_args struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.namespaceName = iprot.readString();
          struct.setNamespaceNameIsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("listNamespaceIterators_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.MAP, (short)0);
    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField OUCH3_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch3", org.apache.thrift.protocol.TType.STRUCT, (short)3);

    private static final 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 java.util.Map<java.lang.String,java.util.Set<IteratorScope>> success; // required
    public AccumuloException ouch1; // required
    public AccumuloSecurityException ouch2; // required
    public NamespaceNotFoundException ouch3; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      OUCH1((short)1, "ouch1"),
      OUCH2((short)2, "ouch2"),
      OUCH3((short)3, "ouch3");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // OUCH1
            return OUCH1;
          case 2: // OUCH2
            return OUCH2;
          case 3: // OUCH3
            return OUCH3;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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.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.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);
    }

    public listNamespaceIterators_result() {
    }

    public listNamespaceIterators_result(
      java.util.Map<java.lang.String,java.util.Set<IteratorScope>> success,
      AccumuloException ouch1,
      AccumuloSecurityException ouch2,
      NamespaceNotFoundException ouch3)
    {
      this();
      this.success = success;
      this.ouch1 = ouch1;
      this.ouch2 = ouch2;
      this.ouch3 = ouch3;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public listNamespaceIterators_result(listNamespaceIterators_result other) {
      if (other.isSetSuccess()) {
        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()) {

          java.lang.String other_element_key = other_element.getKey();
          java.util.Set<IteratorScope> other_element_value = other_element.getValue();

          java.lang.String __this__success_copy_key = other_element_key;

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

          __this__success.put(__this__success_copy_key, __this__success_copy_value);
        }
        this.success = __this__success;
      }
      if (other.isSetOuch1()) {
        this.ouch1 = new AccumuloException(other.ouch1);
      }
      if (other.isSetOuch2()) {
        this.ouch2 = new AccumuloSecurityException(other.ouch2);
      }
      if (other.isSetOuch3()) {
        this.ouch3 = new NamespaceNotFoundException(other.ouch3);
      }
    }

    public listNamespaceIterators_result deepCopy() {
      return new listNamespaceIterators_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ouch1 = null;
      this.ouch2 = null;
      this.ouch3 = null;
    }

    public int getSuccessSize() {
      return (this.success == null) ? 0 : this.success.size();
    }

    public void putToSuccess(java.lang.String key, java.util.Set<IteratorScope> val) {
      if (this.success == null) {
        this.success = new java.util.HashMap<java.lang.String,java.util.Set<IteratorScope>>();
      }
      this.success.put(key, val);
    }

    public java.util.Map<java.lang.String,java.util.Set<IteratorScope>> getSuccess() {
      return this.success;
    }

    public listNamespaceIterators_result setSuccess(java.util.Map<java.lang.String,java.util.Set<IteratorScope>> success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return this.success != null;
    }

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public AccumuloException getOuch1() {
      return this.ouch1;
    }

    public listNamespaceIterators_result setOuch1(AccumuloException ouch1) {
      this.ouch1 = ouch1;
      return this;
    }

    public void unsetOuch1() {
      this.ouch1 = null;
    }

    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch1() {
      return this.ouch1 != null;
    }

    public void setOuch1IsSet(boolean value) {
      if (!value) {
        this.ouch1 = null;
      }
    }

    public AccumuloSecurityException getOuch2() {
      return this.ouch2;
    }

    public listNamespaceIterators_result setOuch2(AccumuloSecurityException ouch2) {
      this.ouch2 = ouch2;
      return this;
    }

    public void unsetOuch2() {
      this.ouch2 = null;
    }

    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch2() {
      return this.ouch2 != null;
    }

    public void setOuch2IsSet(boolean value) {
      if (!value) {
        this.ouch2 = null;
      }
    }

    public NamespaceNotFoundException getOuch3() {
      return this.ouch3;
    }

    public listNamespaceIterators_result setOuch3(NamespaceNotFoundException ouch3) {
      this.ouch3 = ouch3;
      return this;
    }

    public void unsetOuch3() {
      this.ouch3 = null;
    }

    /** Returns true if field ouch3 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch3() {
      return this.ouch3 != null;
    }

    public void setOuch3IsSet(boolean value) {
      if (!value) {
        this.ouch3 = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.util.Map<java.lang.String,java.util.Set<IteratorScope>>)value);
        }
        break;

      case OUCH1:
        if (value == null) {
          unsetOuch1();
        } else {
          setOuch1((AccumuloException)value);
        }
        break;

      case OUCH2:
        if (value == null) {
          unsetOuch2();
        } else {
          setOuch2((AccumuloSecurityException)value);
        }
        break;

      case OUCH3:
        if (value == null) {
          unsetOuch3();
        } else {
          setOuch3((NamespaceNotFoundException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case OUCH1:
        return getOuch1();

      case OUCH2:
        return getOuch2();

      case OUCH3:
        return getOuch3();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case OUCH1:
        return isSetOuch1();
      case OUCH2:
        return isSetOuch2();
      case OUCH3:
        return isSetOuch3();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof listNamespaceIterators_result)
        return this.equals((listNamespaceIterators_result)that);
      return false;
    }

    public boolean equals(listNamespaceIterators_result that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ouch1 = true && this.isSetOuch1();
      boolean that_present_ouch1 = true && that.isSetOuch1();
      if (this_present_ouch1 || that_present_ouch1) {
        if (!(this_present_ouch1 && that_present_ouch1))
          return false;
        if (!this.ouch1.equals(that.ouch1))
          return false;
      }

      boolean this_present_ouch2 = true && this.isSetOuch2();
      boolean that_present_ouch2 = true && that.isSetOuch2();
      if (this_present_ouch2 || that_present_ouch2) {
        if (!(this_present_ouch2 && that_present_ouch2))
          return false;
        if (!this.ouch2.equals(that.ouch2))
          return false;
      }

      boolean this_present_ouch3 = true && this.isSetOuch3();
      boolean that_present_ouch3 = true && that.isSetOuch3();
      if (this_present_ouch3 || that_present_ouch3) {
        if (!(this_present_ouch3 && that_present_ouch3))
          return false;
        if (!this.ouch3.equals(that.ouch3))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
      if (isSetSuccess())
        hashCode = hashCode * 8191 + success.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
      if (isSetOuch1())
        hashCode = hashCode * 8191 + ouch1.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
      if (isSetOuch2())
        hashCode = hashCode * 8191 + ouch2.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
      if (isSetOuch3())
        hashCode = hashCode * 8191 + ouch3.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(listNamespaceIterators_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch1()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch2()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch3()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch3, other.ouch3);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("listNamespaceIterators_result(");
      boolean first = true;

      sb.append("success:");
      if (this.success == null) {
        sb.append("null");
      } else {
        sb.append(this.success);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch1:");
      if (this.ouch1 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch1);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch2:");
      if (this.ouch2 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch2);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch3:");
      if (this.ouch3 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch3);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class listNamespaceIterators_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public listNamespaceIterators_resultStandardScheme getScheme() {
        return new listNamespaceIterators_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.MAP) {
                {
                  org.apache.thrift.protocol.TMap _map542 = iprot.readMapBegin();
                  struct.success = new 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 java.util.HashSet<IteratorScope>(2*_set546.size);
                      IteratorScope _elem547;
                      for (int _i548 = 0; _i548 < _set546.size; ++_i548)
                      {
                        _elem547 = org.apache.accumulo.proxy.thrift.IteratorScope.findByValue(iprot.readI32());
                        _val544.add(_elem547);
                      }
                      iprot.readSetEnd();
                    }
                    struct.success.put(_key543, _val544);
                  }
                  iprot.readMapEnd();
                }
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // OUCH1
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch1 = new AccumuloException();
                struct.ouch1.read(iprot);
                struct.setOuch1IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OUCH2
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch2 = new AccumuloSecurityException();
                struct.ouch2.read(iprot);
                struct.setOuch2IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // OUCH3
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch3 = new NamespaceNotFoundException();
                struct.ouch3.read(iprot);
                struct.setOuch3IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, listNamespaceIterators_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          {
            oprot.writeMapBegin(new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.SET, struct.success.size()));
            for (java.util.Map.Entry<java.lang.String, java.util.Set<IteratorScope>> _iter549 : struct.success.entrySet())
            {
              oprot.writeString(_iter549.getKey());
              {
                oprot.writeSetBegin(new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.I32, _iter549.getValue().size()));
                for (IteratorScope _iter550 : _iter549.getValue())
                {
                  oprot.writeI32(_iter550.getValue());
                }
                oprot.writeSetEnd();
              }
            }
            oprot.writeMapEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.ouch1 != null) {
          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
          struct.ouch1.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch2 != null) {
          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
          struct.ouch2.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch3 != null) {
          oprot.writeFieldBegin(OUCH3_FIELD_DESC);
          struct.ouch3.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class listNamespaceIterators_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public listNamespaceIterators_resultTupleScheme getScheme() {
        return new listNamespaceIterators_resultTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetOuch1()) {
          optionals.set(1);
        }
        if (struct.isSetOuch2()) {
          optionals.set(2);
        }
        if (struct.isSetOuch3()) {
          optionals.set(3);
        }
        oprot.writeBitSet(optionals, 4);
        if (struct.isSetSuccess()) {
          {
            oprot.writeI32(struct.success.size());
            for (java.util.Map.Entry<java.lang.String, java.util.Set<IteratorScope>> _iter551 : struct.success.entrySet())
            {
              oprot.writeString(_iter551.getKey());
              {
                oprot.writeI32(_iter551.getValue().size());
                for (IteratorScope _iter552 : _iter551.getValue())
                {
                  oprot.writeI32(_iter552.getValue());
                }
              }
            }
          }
        }
        if (struct.isSetOuch1()) {
          struct.ouch1.write(oprot);
        }
        if (struct.isSetOuch2()) {
          struct.ouch2.write(oprot);
        }
        if (struct.isSetOuch3()) {
          struct.ouch3.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, listNamespaceIterators_result struct) throws org.apache.thrift.TException {
        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 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 java.util.HashSet<IteratorScope>(2*_set557.size);
                IteratorScope _elem558;
                for (int _i559 = 0; _i559 < _set557.size; ++_i559)
                {
                  _elem558 = org.apache.accumulo.proxy.thrift.IteratorScope.findByValue(iprot.readI32());
                  _val555.add(_elem558);
                }
              }
              struct.success.put(_key554, _val555);
            }
          }
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ouch1 = new AccumuloException();
          struct.ouch1.read(iprot);
          struct.setOuch1IsSet(true);
        }
        if (incoming.get(2)) {
          struct.ouch2 = new AccumuloSecurityException();
          struct.ouch2.read(iprot);
          struct.setOuch2IsSet(true);
        }
        if (incoming.get(3)) {
          struct.ouch3 = new NamespaceNotFoundException();
          struct.ouch3.read(iprot);
          struct.setOuch3IsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("checkNamespaceIteratorConflicts_args");

    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField NAMESPACE_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("namespaceName", org.apache.thrift.protocol.TType.STRING, (short)2);
    private static final org.apache.thrift.protocol.TField SETTING_FIELD_DESC = new org.apache.thrift.protocol.TField("setting", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    private static final org.apache.thrift.protocol.TField SCOPES_FIELD_DESC = new org.apache.thrift.protocol.TField("scopes", org.apache.thrift.protocol.TType.SET, (short)4);

    private static final 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 java.nio.ByteBuffer login; // required
    public java.lang.String namespaceName; // required
    public IteratorSetting setting; // 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 {
      LOGIN((short)1, "login"),
      NAMESPACE_NAME((short)2, "namespaceName"),
      SETTING((short)3, "setting"),
      SCOPES((short)4, "scopes");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // LOGIN
            return LOGIN;
          case 2: // NAMESPACE_NAME
            return NAMESPACE_NAME;
          case 3: // SETTING
            return SETTING;
          case 4: // SCOPES
            return SCOPES;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.SETTING, new org.apache.thrift.meta_data.FieldMetaData("setting", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, IteratorSetting.class)));
      tmpMap.put(_Fields.SCOPES, new org.apache.thrift.meta_data.FieldMetaData("scopes", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.SetMetaData(org.apache.thrift.protocol.TType.SET, 
              new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, IteratorScope.class))));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(checkNamespaceIteratorConflicts_args.class, metaDataMap);
    }

    public checkNamespaceIteratorConflicts_args() {
    }

    public checkNamespaceIteratorConflicts_args(
      java.nio.ByteBuffer login,
      java.lang.String namespaceName,
      IteratorSetting setting,
      java.util.Set<IteratorScope> scopes)
    {
      this();
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      this.namespaceName = namespaceName;
      this.setting = setting;
      this.scopes = scopes;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public checkNamespaceIteratorConflicts_args(checkNamespaceIteratorConflicts_args other) {
      if (other.isSetLogin()) {
        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
      }
      if (other.isSetNamespaceName()) {
        this.namespaceName = other.namespaceName;
      }
      if (other.isSetSetting()) {
        this.setting = new IteratorSetting(other.setting);
      }
      if (other.isSetScopes()) {
        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);
        }
        this.scopes = __this__scopes;
      }
    }

    public checkNamespaceIteratorConflicts_args deepCopy() {
      return new checkNamespaceIteratorConflicts_args(this);
    }

    @Override
    public void clear() {
      this.login = null;
      this.namespaceName = null;
      this.setting = null;
      this.scopes = null;
    }

    public byte[] getLogin() {
      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
      return login == null ? null : login.array();
    }

    public java.nio.ByteBuffer bufferForLogin() {
      return org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    public checkNamespaceIteratorConflicts_args setLogin(byte[] login) {
      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
      return this;
    }

    public checkNamespaceIteratorConflicts_args setLogin(java.nio.ByteBuffer login) {
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      return this;
    }

    public void unsetLogin() {
      this.login = null;
    }

    /** Returns true if field login is set (has been assigned a value) and false otherwise */
    public boolean isSetLogin() {
      return this.login != null;
    }

    public void setLoginIsSet(boolean value) {
      if (!value) {
        this.login = null;
      }
    }

    public java.lang.String getNamespaceName() {
      return this.namespaceName;
    }

    public checkNamespaceIteratorConflicts_args setNamespaceName(java.lang.String namespaceName) {
      this.namespaceName = namespaceName;
      return this;
    }

    public void unsetNamespaceName() {
      this.namespaceName = null;
    }

    /** Returns true if field namespaceName is set (has been assigned a value) and false otherwise */
    public boolean isSetNamespaceName() {
      return this.namespaceName != null;
    }

    public void setNamespaceNameIsSet(boolean value) {
      if (!value) {
        this.namespaceName = null;
      }
    }

    public IteratorSetting getSetting() {
      return this.setting;
    }

    public checkNamespaceIteratorConflicts_args setSetting(IteratorSetting setting) {
      this.setting = setting;
      return this;
    }

    public void unsetSetting() {
      this.setting = null;
    }

    /** Returns true if field setting is set (has been assigned a value) and false otherwise */
    public boolean isSetSetting() {
      return this.setting != null;
    }

    public void setSettingIsSet(boolean value) {
      if (!value) {
        this.setting = null;
      }
    }

    public int getScopesSize() {
      return (this.scopes == null) ? 0 : this.scopes.size();
    }

    public java.util.Iterator<IteratorScope> getScopesIterator() {
      return (this.scopes == null) ? null : this.scopes.iterator();
    }

    public void addToScopes(IteratorScope elem) {
      if (this.scopes == null) {
        this.scopes = new java.util.HashSet<IteratorScope>();
      }
      this.scopes.add(elem);
    }

    public java.util.Set<IteratorScope> getScopes() {
      return this.scopes;
    }

    public checkNamespaceIteratorConflicts_args setScopes(java.util.Set<IteratorScope> scopes) {
      this.scopes = scopes;
      return this;
    }

    public void unsetScopes() {
      this.scopes = null;
    }

    /** Returns true if field scopes is set (has been assigned a value) and false otherwise */
    public boolean isSetScopes() {
      return this.scopes != null;
    }

    public void setScopesIsSet(boolean value) {
      if (!value) {
        this.scopes = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case LOGIN:
        if (value == null) {
          unsetLogin();
        } else {
          if (value instanceof byte[]) {
            setLogin((byte[])value);
          } else {
            setLogin((java.nio.ByteBuffer)value);
          }
        }
        break;

      case NAMESPACE_NAME:
        if (value == null) {
          unsetNamespaceName();
        } else {
          setNamespaceName((java.lang.String)value);
        }
        break;

      case SETTING:
        if (value == null) {
          unsetSetting();
        } else {
          setSetting((IteratorSetting)value);
        }
        break;

      case SCOPES:
        if (value == null) {
          unsetScopes();
        } else {
          setScopes((java.util.Set<IteratorScope>)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case LOGIN:
        return getLogin();

      case NAMESPACE_NAME:
        return getNamespaceName();

      case SETTING:
        return getSetting();

      case SCOPES:
        return getScopes();

      }
      throw new 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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case LOGIN:
        return isSetLogin();
      case NAMESPACE_NAME:
        return isSetNamespaceName();
      case SETTING:
        return isSetSetting();
      case SCOPES:
        return isSetScopes();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof checkNamespaceIteratorConflicts_args)
        return this.equals((checkNamespaceIteratorConflicts_args)that);
      return false;
    }

    public boolean equals(checkNamespaceIteratorConflicts_args that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_login = true && this.isSetLogin();
      boolean that_present_login = true && that.isSetLogin();
      if (this_present_login || that_present_login) {
        if (!(this_present_login && that_present_login))
          return false;
        if (!this.login.equals(that.login))
          return false;
      }

      boolean this_present_namespaceName = true && this.isSetNamespaceName();
      boolean that_present_namespaceName = true && that.isSetNamespaceName();
      if (this_present_namespaceName || that_present_namespaceName) {
        if (!(this_present_namespaceName && that_present_namespaceName))
          return false;
        if (!this.namespaceName.equals(that.namespaceName))
          return false;
      }

      boolean this_present_setting = true && this.isSetSetting();
      boolean that_present_setting = true && that.isSetSetting();
      if (this_present_setting || that_present_setting) {
        if (!(this_present_setting && that_present_setting))
          return false;
        if (!this.setting.equals(that.setting))
          return false;
      }

      boolean this_present_scopes = true && this.isSetScopes();
      boolean that_present_scopes = true && that.isSetScopes();
      if (this_present_scopes || that_present_scopes) {
        if (!(this_present_scopes && that_present_scopes))
          return false;
        if (!this.scopes.equals(that.scopes))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
      if (isSetLogin())
        hashCode = hashCode * 8191 + login.hashCode();

      hashCode = hashCode * 8191 + ((isSetNamespaceName()) ? 131071 : 524287);
      if (isSetNamespaceName())
        hashCode = hashCode * 8191 + namespaceName.hashCode();

      hashCode = hashCode * 8191 + ((isSetSetting()) ? 131071 : 524287);
      if (isSetSetting())
        hashCode = hashCode * 8191 + setting.hashCode();

      hashCode = hashCode * 8191 + ((isSetScopes()) ? 131071 : 524287);
      if (isSetScopes())
        hashCode = hashCode * 8191 + scopes.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(checkNamespaceIteratorConflicts_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLogin()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetNamespaceName()).compareTo(other.isSetNamespaceName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetNamespaceName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.namespaceName, other.namespaceName);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetSetting()).compareTo(other.isSetSetting());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSetting()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.setting, other.setting);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetScopes()).compareTo(other.isSetScopes());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetScopes()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.scopes, other.scopes);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("checkNamespaceIteratorConflicts_args(");
      boolean first = true;

      sb.append("login:");
      if (this.login == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.login, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("namespaceName:");
      if (this.namespaceName == null) {
        sb.append("null");
      } else {
        sb.append(this.namespaceName);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("setting:");
      if (this.setting == null) {
        sb.append("null");
      } else {
        sb.append(this.setting);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("scopes:");
      if (this.scopes == null) {
        sb.append("null");
      } else {
        sb.append(this.scopes);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
      if (setting != null) {
        setting.validate();
      }
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class checkNamespaceIteratorConflicts_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public checkNamespaceIteratorConflicts_argsStandardScheme getScheme() {
        return new checkNamespaceIteratorConflicts_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // LOGIN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.login = iprot.readBinary();
                struct.setLoginIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // NAMESPACE_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.namespaceName = iprot.readString();
                struct.setNamespaceNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // SETTING
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.setting = new IteratorSetting();
                struct.setting.read(iprot);
                struct.setSettingIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // SCOPES
              if (schemeField.type == org.apache.thrift.protocol.TType.SET) {
                {
                  org.apache.thrift.protocol.TSet _set560 = iprot.readSetBegin();
                  struct.scopes = new java.util.HashSet<IteratorScope>(2*_set560.size);
                  IteratorScope _elem561;
                  for (int _i562 = 0; _i562 < _set560.size; ++_i562)
                  {
                    _elem561 = org.apache.accumulo.proxy.thrift.IteratorScope.findByValue(iprot.readI32());
                    struct.scopes.add(_elem561);
                  }
                  iprot.readSetEnd();
                }
                struct.setScopesIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, checkNamespaceIteratorConflicts_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.login != null) {
          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
          oprot.writeBinary(struct.login);
          oprot.writeFieldEnd();
        }
        if (struct.namespaceName != null) {
          oprot.writeFieldBegin(NAMESPACE_NAME_FIELD_DESC);
          oprot.writeString(struct.namespaceName);
          oprot.writeFieldEnd();
        }
        if (struct.setting != null) {
          oprot.writeFieldBegin(SETTING_FIELD_DESC);
          struct.setting.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.scopes != null) {
          oprot.writeFieldBegin(SCOPES_FIELD_DESC);
          {
            oprot.writeSetBegin(new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.I32, struct.scopes.size()));
            for (IteratorScope _iter563 : struct.scopes)
            {
              oprot.writeI32(_iter563.getValue());
            }
            oprot.writeSetEnd();
          }
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class checkNamespaceIteratorConflicts_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public checkNamespaceIteratorConflicts_argsTupleScheme getScheme() {
        return new checkNamespaceIteratorConflicts_argsTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetNamespaceName()) {
          optionals.set(1);
        }
        if (struct.isSetSetting()) {
          optionals.set(2);
        }
        if (struct.isSetScopes()) {
          optionals.set(3);
        }
        oprot.writeBitSet(optionals, 4);
        if (struct.isSetLogin()) {
          oprot.writeBinary(struct.login);
        }
        if (struct.isSetNamespaceName()) {
          oprot.writeString(struct.namespaceName);
        }
        if (struct.isSetSetting()) {
          struct.setting.write(oprot);
        }
        if (struct.isSetScopes()) {
          {
            oprot.writeI32(struct.scopes.size());
            for (IteratorScope _iter564 : struct.scopes)
            {
              oprot.writeI32(_iter564.getValue());
            }
          }
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, checkNamespaceIteratorConflicts_args struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.namespaceName = iprot.readString();
          struct.setNamespaceNameIsSet(true);
        }
        if (incoming.get(2)) {
          struct.setting = new IteratorSetting();
          struct.setting.read(iprot);
          struct.setSettingIsSet(true);
        }
        if (incoming.get(3)) {
          {
            org.apache.thrift.protocol.TSet _set565 = new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.I32, iprot.readI32());
            struct.scopes = new java.util.HashSet<IteratorScope>(2*_set565.size);
            IteratorScope _elem566;
            for (int _i567 = 0; _i567 < _set565.size; ++_i567)
            {
              _elem566 = org.apache.accumulo.proxy.thrift.IteratorScope.findByValue(iprot.readI32());
              struct.scopes.add(_elem566);
            }
          }
          struct.setScopesIsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("checkNamespaceIteratorConflicts_result");

    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField OUCH3_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch3", org.apache.thrift.protocol.TType.STRUCT, (short)3);

    private static final 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
    public NamespaceNotFoundException ouch3; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      OUCH1((short)1, "ouch1"),
      OUCH2((short)2, "ouch2"),
      OUCH3((short)3, "ouch3");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // OUCH1
            return OUCH1;
          case 2: // OUCH2
            return OUCH2;
          case 3: // OUCH3
            return OUCH3;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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.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.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);
    }

    public checkNamespaceIteratorConflicts_result() {
    }

    public checkNamespaceIteratorConflicts_result(
      AccumuloException ouch1,
      AccumuloSecurityException ouch2,
      NamespaceNotFoundException ouch3)
    {
      this();
      this.ouch1 = ouch1;
      this.ouch2 = ouch2;
      this.ouch3 = ouch3;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public checkNamespaceIteratorConflicts_result(checkNamespaceIteratorConflicts_result other) {
      if (other.isSetOuch1()) {
        this.ouch1 = new AccumuloException(other.ouch1);
      }
      if (other.isSetOuch2()) {
        this.ouch2 = new AccumuloSecurityException(other.ouch2);
      }
      if (other.isSetOuch3()) {
        this.ouch3 = new NamespaceNotFoundException(other.ouch3);
      }
    }

    public checkNamespaceIteratorConflicts_result deepCopy() {
      return new checkNamespaceIteratorConflicts_result(this);
    }

    @Override
    public void clear() {
      this.ouch1 = null;
      this.ouch2 = null;
      this.ouch3 = null;
    }

    public AccumuloException getOuch1() {
      return this.ouch1;
    }

    public checkNamespaceIteratorConflicts_result setOuch1(AccumuloException ouch1) {
      this.ouch1 = ouch1;
      return this;
    }

    public void unsetOuch1() {
      this.ouch1 = null;
    }

    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch1() {
      return this.ouch1 != null;
    }

    public void setOuch1IsSet(boolean value) {
      if (!value) {
        this.ouch1 = null;
      }
    }

    public AccumuloSecurityException getOuch2() {
      return this.ouch2;
    }

    public checkNamespaceIteratorConflicts_result setOuch2(AccumuloSecurityException ouch2) {
      this.ouch2 = ouch2;
      return this;
    }

    public void unsetOuch2() {
      this.ouch2 = null;
    }

    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch2() {
      return this.ouch2 != null;
    }

    public void setOuch2IsSet(boolean value) {
      if (!value) {
        this.ouch2 = null;
      }
    }

    public NamespaceNotFoundException getOuch3() {
      return this.ouch3;
    }

    public checkNamespaceIteratorConflicts_result setOuch3(NamespaceNotFoundException ouch3) {
      this.ouch3 = ouch3;
      return this;
    }

    public void unsetOuch3() {
      this.ouch3 = null;
    }

    /** Returns true if field ouch3 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch3() {
      return this.ouch3 != null;
    }

    public void setOuch3IsSet(boolean value) {
      if (!value) {
        this.ouch3 = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case OUCH1:
        if (value == null) {
          unsetOuch1();
        } else {
          setOuch1((AccumuloException)value);
        }
        break;

      case OUCH2:
        if (value == null) {
          unsetOuch2();
        } else {
          setOuch2((AccumuloSecurityException)value);
        }
        break;

      case OUCH3:
        if (value == null) {
          unsetOuch3();
        } else {
          setOuch3((NamespaceNotFoundException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case OUCH1:
        return getOuch1();

      case OUCH2:
        return getOuch2();

      case OUCH3:
        return getOuch3();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case OUCH1:
        return isSetOuch1();
      case OUCH2:
        return isSetOuch2();
      case OUCH3:
        return isSetOuch3();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof checkNamespaceIteratorConflicts_result)
        return this.equals((checkNamespaceIteratorConflicts_result)that);
      return false;
    }

    public boolean equals(checkNamespaceIteratorConflicts_result that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_ouch1 = true && this.isSetOuch1();
      boolean that_present_ouch1 = true && that.isSetOuch1();
      if (this_present_ouch1 || that_present_ouch1) {
        if (!(this_present_ouch1 && that_present_ouch1))
          return false;
        if (!this.ouch1.equals(that.ouch1))
          return false;
      }

      boolean this_present_ouch2 = true && this.isSetOuch2();
      boolean that_present_ouch2 = true && that.isSetOuch2();
      if (this_present_ouch2 || that_present_ouch2) {
        if (!(this_present_ouch2 && that_present_ouch2))
          return false;
        if (!this.ouch2.equals(that.ouch2))
          return false;
      }

      boolean this_present_ouch3 = true && this.isSetOuch3();
      boolean that_present_ouch3 = true && that.isSetOuch3();
      if (this_present_ouch3 || that_present_ouch3) {
        if (!(this_present_ouch3 && that_present_ouch3))
          return false;
        if (!this.ouch3.equals(that.ouch3))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
      if (isSetOuch1())
        hashCode = hashCode * 8191 + ouch1.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
      if (isSetOuch2())
        hashCode = hashCode * 8191 + ouch2.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
      if (isSetOuch3())
        hashCode = hashCode * 8191 + ouch3.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(checkNamespaceIteratorConflicts_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch1()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch2()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch3()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch3, other.ouch3);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("checkNamespaceIteratorConflicts_result(");
      boolean first = true;

      sb.append("ouch1:");
      if (this.ouch1 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch1);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch2:");
      if (this.ouch2 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch2);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch3:");
      if (this.ouch3 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch3);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class checkNamespaceIteratorConflicts_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public checkNamespaceIteratorConflicts_resultStandardScheme getScheme() {
        return new checkNamespaceIteratorConflicts_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // OUCH1
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch1 = new AccumuloException();
                struct.ouch1.read(iprot);
                struct.setOuch1IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OUCH2
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch2 = new AccumuloSecurityException();
                struct.ouch2.read(iprot);
                struct.setOuch2IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // OUCH3
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch3 = new NamespaceNotFoundException();
                struct.ouch3.read(iprot);
                struct.setOuch3IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, checkNamespaceIteratorConflicts_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.ouch1 != null) {
          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
          struct.ouch1.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch2 != null) {
          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
          struct.ouch2.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch3 != null) {
          oprot.writeFieldBegin(OUCH3_FIELD_DESC);
          struct.ouch3.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class checkNamespaceIteratorConflicts_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public checkNamespaceIteratorConflicts_resultTupleScheme getScheme() {
        return new checkNamespaceIteratorConflicts_resultTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetOuch2()) {
          optionals.set(1);
        }
        if (struct.isSetOuch3()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetOuch1()) {
          struct.ouch1.write(oprot);
        }
        if (struct.isSetOuch2()) {
          struct.ouch2.write(oprot);
        }
        if (struct.isSetOuch3()) {
          struct.ouch3.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, checkNamespaceIteratorConflicts_result struct) throws org.apache.thrift.TException {
        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);
          struct.setOuch1IsSet(true);
        }
        if (incoming.get(1)) {
          struct.ouch2 = new AccumuloSecurityException();
          struct.ouch2.read(iprot);
          struct.setOuch2IsSet(true);
        }
        if (incoming.get(2)) {
          struct.ouch3 = new NamespaceNotFoundException();
          struct.ouch3.read(iprot);
          struct.setOuch3IsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("addNamespaceConstraint_args");

    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField NAMESPACE_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("namespaceName", org.apache.thrift.protocol.TType.STRING, (short)2);
    private static final org.apache.thrift.protocol.TField CONSTRAINT_CLASS_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("constraintClassName", org.apache.thrift.protocol.TType.STRING, (short)3);

    private static final 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 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 {
      LOGIN((short)1, "login"),
      NAMESPACE_NAME((short)2, "namespaceName"),
      CONSTRAINT_CLASS_NAME((short)3, "constraintClassName");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // LOGIN
            return LOGIN;
          case 2: // NAMESPACE_NAME
            return NAMESPACE_NAME;
          case 3: // CONSTRAINT_CLASS_NAME
            return CONSTRAINT_CLASS_NAME;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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 = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(addNamespaceConstraint_args.class, metaDataMap);
    }

    public addNamespaceConstraint_args() {
    }

    public addNamespaceConstraint_args(
      java.nio.ByteBuffer login,
      java.lang.String namespaceName,
      java.lang.String constraintClassName)
    {
      this();
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      this.namespaceName = namespaceName;
      this.constraintClassName = constraintClassName;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public addNamespaceConstraint_args(addNamespaceConstraint_args other) {
      if (other.isSetLogin()) {
        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
      }
      if (other.isSetNamespaceName()) {
        this.namespaceName = other.namespaceName;
      }
      if (other.isSetConstraintClassName()) {
        this.constraintClassName = other.constraintClassName;
      }
    }

    public addNamespaceConstraint_args deepCopy() {
      return new addNamespaceConstraint_args(this);
    }

    @Override
    public void clear() {
      this.login = null;
      this.namespaceName = null;
      this.constraintClassName = null;
    }

    public byte[] getLogin() {
      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
      return login == null ? null : login.array();
    }

    public java.nio.ByteBuffer bufferForLogin() {
      return org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    public addNamespaceConstraint_args setLogin(byte[] login) {
      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
      return this;
    }

    public addNamespaceConstraint_args setLogin(java.nio.ByteBuffer login) {
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      return this;
    }

    public void unsetLogin() {
      this.login = null;
    }

    /** Returns true if field login is set (has been assigned a value) and false otherwise */
    public boolean isSetLogin() {
      return this.login != null;
    }

    public void setLoginIsSet(boolean value) {
      if (!value) {
        this.login = null;
      }
    }

    public java.lang.String getNamespaceName() {
      return this.namespaceName;
    }

    public addNamespaceConstraint_args setNamespaceName(java.lang.String namespaceName) {
      this.namespaceName = namespaceName;
      return this;
    }

    public void unsetNamespaceName() {
      this.namespaceName = null;
    }

    /** Returns true if field namespaceName is set (has been assigned a value) and false otherwise */
    public boolean isSetNamespaceName() {
      return this.namespaceName != null;
    }

    public void setNamespaceNameIsSet(boolean value) {
      if (!value) {
        this.namespaceName = null;
      }
    }

    public java.lang.String getConstraintClassName() {
      return this.constraintClassName;
    }

    public addNamespaceConstraint_args setConstraintClassName(java.lang.String constraintClassName) {
      this.constraintClassName = constraintClassName;
      return this;
    }

    public void unsetConstraintClassName() {
      this.constraintClassName = null;
    }

    /** Returns true if field constraintClassName is set (has been assigned a value) and false otherwise */
    public boolean isSetConstraintClassName() {
      return this.constraintClassName != null;
    }

    public void setConstraintClassNameIsSet(boolean value) {
      if (!value) {
        this.constraintClassName = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case LOGIN:
        if (value == null) {
          unsetLogin();
        } else {
          if (value instanceof byte[]) {
            setLogin((byte[])value);
          } else {
            setLogin((java.nio.ByteBuffer)value);
          }
        }
        break;

      case NAMESPACE_NAME:
        if (value == null) {
          unsetNamespaceName();
        } else {
          setNamespaceName((java.lang.String)value);
        }
        break;

      case CONSTRAINT_CLASS_NAME:
        if (value == null) {
          unsetConstraintClassName();
        } else {
          setConstraintClassName((java.lang.String)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case LOGIN:
        return getLogin();

      case NAMESPACE_NAME:
        return getNamespaceName();

      case CONSTRAINT_CLASS_NAME:
        return getConstraintClassName();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case LOGIN:
        return isSetLogin();
      case NAMESPACE_NAME:
        return isSetNamespaceName();
      case CONSTRAINT_CLASS_NAME:
        return isSetConstraintClassName();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof addNamespaceConstraint_args)
        return this.equals((addNamespaceConstraint_args)that);
      return false;
    }

    public boolean equals(addNamespaceConstraint_args that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_login = true && this.isSetLogin();
      boolean that_present_login = true && that.isSetLogin();
      if (this_present_login || that_present_login) {
        if (!(this_present_login && that_present_login))
          return false;
        if (!this.login.equals(that.login))
          return false;
      }

      boolean this_present_namespaceName = true && this.isSetNamespaceName();
      boolean that_present_namespaceName = true && that.isSetNamespaceName();
      if (this_present_namespaceName || that_present_namespaceName) {
        if (!(this_present_namespaceName && that_present_namespaceName))
          return false;
        if (!this.namespaceName.equals(that.namespaceName))
          return false;
      }

      boolean this_present_constraintClassName = true && this.isSetConstraintClassName();
      boolean that_present_constraintClassName = true && that.isSetConstraintClassName();
      if (this_present_constraintClassName || that_present_constraintClassName) {
        if (!(this_present_constraintClassName && that_present_constraintClassName))
          return false;
        if (!this.constraintClassName.equals(that.constraintClassName))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
      if (isSetLogin())
        hashCode = hashCode * 8191 + login.hashCode();

      hashCode = hashCode * 8191 + ((isSetNamespaceName()) ? 131071 : 524287);
      if (isSetNamespaceName())
        hashCode = hashCode * 8191 + namespaceName.hashCode();

      hashCode = hashCode * 8191 + ((isSetConstraintClassName()) ? 131071 : 524287);
      if (isSetConstraintClassName())
        hashCode = hashCode * 8191 + constraintClassName.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(addNamespaceConstraint_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLogin()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetNamespaceName()).compareTo(other.isSetNamespaceName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetNamespaceName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.namespaceName, other.namespaceName);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetConstraintClassName()).compareTo(other.isSetConstraintClassName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetConstraintClassName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.constraintClassName, other.constraintClassName);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("addNamespaceConstraint_args(");
      boolean first = true;

      sb.append("login:");
      if (this.login == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.login, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("namespaceName:");
      if (this.namespaceName == null) {
        sb.append("null");
      } else {
        sb.append(this.namespaceName);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("constraintClassName:");
      if (this.constraintClassName == null) {
        sb.append("null");
      } else {
        sb.append(this.constraintClassName);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class addNamespaceConstraint_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public addNamespaceConstraint_argsStandardScheme getScheme() {
        return new addNamespaceConstraint_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // LOGIN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.login = iprot.readBinary();
                struct.setLoginIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // NAMESPACE_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.namespaceName = iprot.readString();
                struct.setNamespaceNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // CONSTRAINT_CLASS_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.constraintClassName = iprot.readString();
                struct.setConstraintClassNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, addNamespaceConstraint_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.login != null) {
          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
          oprot.writeBinary(struct.login);
          oprot.writeFieldEnd();
        }
        if (struct.namespaceName != null) {
          oprot.writeFieldBegin(NAMESPACE_NAME_FIELD_DESC);
          oprot.writeString(struct.namespaceName);
          oprot.writeFieldEnd();
        }
        if (struct.constraintClassName != null) {
          oprot.writeFieldBegin(CONSTRAINT_CLASS_NAME_FIELD_DESC);
          oprot.writeString(struct.constraintClassName);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class addNamespaceConstraint_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public addNamespaceConstraint_argsTupleScheme getScheme() {
        return new addNamespaceConstraint_argsTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetNamespaceName()) {
          optionals.set(1);
        }
        if (struct.isSetConstraintClassName()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetLogin()) {
          oprot.writeBinary(struct.login);
        }
        if (struct.isSetNamespaceName()) {
          oprot.writeString(struct.namespaceName);
        }
        if (struct.isSetConstraintClassName()) {
          oprot.writeString(struct.constraintClassName);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, addNamespaceConstraint_args struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.namespaceName = iprot.readString();
          struct.setNamespaceNameIsSet(true);
        }
        if (incoming.get(2)) {
          struct.constraintClassName = iprot.readString();
          struct.setConstraintClassNameIsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("addNamespaceConstraint_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.I32, (short)0);
    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField OUCH3_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch3", org.apache.thrift.protocol.TType.STRUCT, (short)3);

    private static final 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
    public AccumuloSecurityException ouch2; // required
    public NamespaceNotFoundException ouch3; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      OUCH1((short)1, "ouch1"),
      OUCH2((short)2, "ouch2"),
      OUCH3((short)3, "ouch3");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // OUCH1
            return OUCH1;
          case 2: // OUCH2
            return OUCH2;
          case 3: // OUCH3
            return OUCH3;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __SUCCESS_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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.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.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);
    }

    public addNamespaceConstraint_result() {
    }

    public addNamespaceConstraint_result(
      int success,
      AccumuloException ouch1,
      AccumuloSecurityException ouch2,
      NamespaceNotFoundException ouch3)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
      this.ouch1 = ouch1;
      this.ouch2 = ouch2;
      this.ouch3 = ouch3;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public addNamespaceConstraint_result(addNamespaceConstraint_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
      if (other.isSetOuch1()) {
        this.ouch1 = new AccumuloException(other.ouch1);
      }
      if (other.isSetOuch2()) {
        this.ouch2 = new AccumuloSecurityException(other.ouch2);
      }
      if (other.isSetOuch3()) {
        this.ouch3 = new NamespaceNotFoundException(other.ouch3);
      }
    }

    public addNamespaceConstraint_result deepCopy() {
      return new addNamespaceConstraint_result(this);
    }

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = 0;
      this.ouch1 = null;
      this.ouch2 = null;
      this.ouch3 = null;
    }

    public int getSuccess() {
      return this.success;
    }

    public addNamespaceConstraint_result setSuccess(int success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

    public void unsetSuccess() {
      __isset_bitfield = 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 org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    public void setSuccessIsSet(boolean value) {
      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
    }

    public AccumuloException getOuch1() {
      return this.ouch1;
    }

    public addNamespaceConstraint_result setOuch1(AccumuloException ouch1) {
      this.ouch1 = ouch1;
      return this;
    }

    public void unsetOuch1() {
      this.ouch1 = null;
    }

    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch1() {
      return this.ouch1 != null;
    }

    public void setOuch1IsSet(boolean value) {
      if (!value) {
        this.ouch1 = null;
      }
    }

    public AccumuloSecurityException getOuch2() {
      return this.ouch2;
    }

    public addNamespaceConstraint_result setOuch2(AccumuloSecurityException ouch2) {
      this.ouch2 = ouch2;
      return this;
    }

    public void unsetOuch2() {
      this.ouch2 = null;
    }

    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch2() {
      return this.ouch2 != null;
    }

    public void setOuch2IsSet(boolean value) {
      if (!value) {
        this.ouch2 = null;
      }
    }

    public NamespaceNotFoundException getOuch3() {
      return this.ouch3;
    }

    public addNamespaceConstraint_result setOuch3(NamespaceNotFoundException ouch3) {
      this.ouch3 = ouch3;
      return this;
    }

    public void unsetOuch3() {
      this.ouch3 = null;
    }

    /** Returns true if field ouch3 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch3() {
      return this.ouch3 != null;
    }

    public void setOuch3IsSet(boolean value) {
      if (!value) {
        this.ouch3 = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.lang.Integer)value);
        }
        break;

      case OUCH1:
        if (value == null) {
          unsetOuch1();
        } else {
          setOuch1((AccumuloException)value);
        }
        break;

      case OUCH2:
        if (value == null) {
          unsetOuch2();
        } else {
          setOuch2((AccumuloSecurityException)value);
        }
        break;

      case OUCH3:
        if (value == null) {
          unsetOuch3();
        } else {
          setOuch3((NamespaceNotFoundException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case OUCH1:
        return getOuch1();

      case OUCH2:
        return getOuch2();

      case OUCH3:
        return getOuch3();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case OUCH1:
        return isSetOuch1();
      case OUCH2:
        return isSetOuch2();
      case OUCH3:
        return isSetOuch3();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof addNamespaceConstraint_result)
        return this.equals((addNamespaceConstraint_result)that);
      return false;
    }

    public boolean equals(addNamespaceConstraint_result that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_success = true;
      boolean that_present_success = true;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      boolean this_present_ouch1 = true && this.isSetOuch1();
      boolean that_present_ouch1 = true && that.isSetOuch1();
      if (this_present_ouch1 || that_present_ouch1) {
        if (!(this_present_ouch1 && that_present_ouch1))
          return false;
        if (!this.ouch1.equals(that.ouch1))
          return false;
      }

      boolean this_present_ouch2 = true && this.isSetOuch2();
      boolean that_present_ouch2 = true && that.isSetOuch2();
      if (this_present_ouch2 || that_present_ouch2) {
        if (!(this_present_ouch2 && that_present_ouch2))
          return false;
        if (!this.ouch2.equals(that.ouch2))
          return false;
      }

      boolean this_present_ouch3 = true && this.isSetOuch3();
      boolean that_present_ouch3 = true && that.isSetOuch3();
      if (this_present_ouch3 || that_present_ouch3) {
        if (!(this_present_ouch3 && that_present_ouch3))
          return false;
        if (!this.ouch3.equals(that.ouch3))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + success;

      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
      if (isSetOuch1())
        hashCode = hashCode * 8191 + ouch1.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
      if (isSetOuch2())
        hashCode = hashCode * 8191 + ouch2.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
      if (isSetOuch3())
        hashCode = hashCode * 8191 + ouch3.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(addNamespaceConstraint_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch1()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch2()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch3()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch3, other.ouch3);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("addNamespaceConstraint_result(");
      boolean first = true;

      sb.append("success:");
      sb.append(this.success);
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch1:");
      if (this.ouch1 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch1);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch2:");
      if (this.ouch2 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch2);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch3:");
      if (this.ouch3 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch3);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, 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;
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class addNamespaceConstraint_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public addNamespaceConstraint_resultStandardScheme getScheme() {
        return new addNamespaceConstraint_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.success = iprot.readI32();
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // OUCH1
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch1 = new AccumuloException();
                struct.ouch1.read(iprot);
                struct.setOuch1IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OUCH2
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch2 = new AccumuloSecurityException();
                struct.ouch2.read(iprot);
                struct.setOuch2IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // OUCH3
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch3 = new NamespaceNotFoundException();
                struct.ouch3.read(iprot);
                struct.setOuch3IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, addNamespaceConstraint_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.isSetSuccess()) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          oprot.writeI32(struct.success);
          oprot.writeFieldEnd();
        }
        if (struct.ouch1 != null) {
          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
          struct.ouch1.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch2 != null) {
          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
          struct.ouch2.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch3 != null) {
          oprot.writeFieldBegin(OUCH3_FIELD_DESC);
          struct.ouch3.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class addNamespaceConstraint_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public addNamespaceConstraint_resultTupleScheme getScheme() {
        return new addNamespaceConstraint_resultTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetOuch1()) {
          optionals.set(1);
        }
        if (struct.isSetOuch2()) {
          optionals.set(2);
        }
        if (struct.isSetOuch3()) {
          optionals.set(3);
        }
        oprot.writeBitSet(optionals, 4);
        if (struct.isSetSuccess()) {
          oprot.writeI32(struct.success);
        }
        if (struct.isSetOuch1()) {
          struct.ouch1.write(oprot);
        }
        if (struct.isSetOuch2()) {
          struct.ouch2.write(oprot);
        }
        if (struct.isSetOuch3()) {
          struct.ouch3.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, addNamespaceConstraint_result struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.ouch1 = new AccumuloException();
          struct.ouch1.read(iprot);
          struct.setOuch1IsSet(true);
        }
        if (incoming.get(2)) {
          struct.ouch2 = new AccumuloSecurityException();
          struct.ouch2.read(iprot);
          struct.setOuch2IsSet(true);
        }
        if (incoming.get(3)) {
          struct.ouch3 = new NamespaceNotFoundException();
          struct.ouch3.read(iprot);
          struct.setOuch3IsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("removeNamespaceConstraint_args");

    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField NAMESPACE_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("namespaceName", org.apache.thrift.protocol.TType.STRING, (short)2);
    private static final org.apache.thrift.protocol.TField ID_FIELD_DESC = new org.apache.thrift.protocol.TField("id", org.apache.thrift.protocol.TType.I32, (short)3);

    private static final 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 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. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      LOGIN((short)1, "login"),
      NAMESPACE_NAME((short)2, "namespaceName"),
      ID((short)3, "id");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // LOGIN
            return LOGIN;
          case 2: // NAMESPACE_NAME
            return NAMESPACE_NAME;
          case 3: // ID
            return ID;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __ID_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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 = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(removeNamespaceConstraint_args.class, metaDataMap);
    }

    public removeNamespaceConstraint_args() {
    }

    public removeNamespaceConstraint_args(
      java.nio.ByteBuffer login,
      java.lang.String namespaceName,
      int id)
    {
      this();
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      this.namespaceName = namespaceName;
      this.id = id;
      setIdIsSet(true);
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public removeNamespaceConstraint_args(removeNamespaceConstraint_args other) {
      __isset_bitfield = other.__isset_bitfield;
      if (other.isSetLogin()) {
        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
      }
      if (other.isSetNamespaceName()) {
        this.namespaceName = other.namespaceName;
      }
      this.id = other.id;
    }

    public removeNamespaceConstraint_args deepCopy() {
      return new removeNamespaceConstraint_args(this);
    }

    @Override
    public void clear() {
      this.login = null;
      this.namespaceName = null;
      setIdIsSet(false);
      this.id = 0;
    }

    public byte[] getLogin() {
      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
      return login == null ? null : login.array();
    }

    public java.nio.ByteBuffer bufferForLogin() {
      return org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    public removeNamespaceConstraint_args setLogin(byte[] login) {
      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
      return this;
    }

    public removeNamespaceConstraint_args setLogin(java.nio.ByteBuffer login) {
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      return this;
    }

    public void unsetLogin() {
      this.login = null;
    }

    /** Returns true if field login is set (has been assigned a value) and false otherwise */
    public boolean isSetLogin() {
      return this.login != null;
    }

    public void setLoginIsSet(boolean value) {
      if (!value) {
        this.login = null;
      }
    }

    public java.lang.String getNamespaceName() {
      return this.namespaceName;
    }

    public removeNamespaceConstraint_args setNamespaceName(java.lang.String namespaceName) {
      this.namespaceName = namespaceName;
      return this;
    }

    public void unsetNamespaceName() {
      this.namespaceName = null;
    }

    /** Returns true if field namespaceName is set (has been assigned a value) and false otherwise */
    public boolean isSetNamespaceName() {
      return this.namespaceName != null;
    }

    public void setNamespaceNameIsSet(boolean value) {
      if (!value) {
        this.namespaceName = null;
      }
    }

    public int getId() {
      return this.id;
    }

    public removeNamespaceConstraint_args setId(int id) {
      this.id = id;
      setIdIsSet(true);
      return this;
    }

    public void unsetId() {
      __isset_bitfield = 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 org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __ID_ISSET_ID);
    }

    public void setIdIsSet(boolean value) {
      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __ID_ISSET_ID, value);
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case LOGIN:
        if (value == null) {
          unsetLogin();
        } else {
          if (value instanceof byte[]) {
            setLogin((byte[])value);
          } else {
            setLogin((java.nio.ByteBuffer)value);
          }
        }
        break;

      case NAMESPACE_NAME:
        if (value == null) {
          unsetNamespaceName();
        } else {
          setNamespaceName((java.lang.String)value);
        }
        break;

      case ID:
        if (value == null) {
          unsetId();
        } else {
          setId((java.lang.Integer)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case LOGIN:
        return getLogin();

      case NAMESPACE_NAME:
        return getNamespaceName();

      case ID:
        return getId();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case LOGIN:
        return isSetLogin();
      case NAMESPACE_NAME:
        return isSetNamespaceName();
      case ID:
        return isSetId();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof removeNamespaceConstraint_args)
        return this.equals((removeNamespaceConstraint_args)that);
      return false;
    }

    public boolean equals(removeNamespaceConstraint_args that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_login = true && this.isSetLogin();
      boolean that_present_login = true && that.isSetLogin();
      if (this_present_login || that_present_login) {
        if (!(this_present_login && that_present_login))
          return false;
        if (!this.login.equals(that.login))
          return false;
      }

      boolean this_present_namespaceName = true && this.isSetNamespaceName();
      boolean that_present_namespaceName = true && that.isSetNamespaceName();
      if (this_present_namespaceName || that_present_namespaceName) {
        if (!(this_present_namespaceName && that_present_namespaceName))
          return false;
        if (!this.namespaceName.equals(that.namespaceName))
          return false;
      }

      boolean this_present_id = true;
      boolean that_present_id = true;
      if (this_present_id || that_present_id) {
        if (!(this_present_id && that_present_id))
          return false;
        if (this.id != that.id)
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
      if (isSetLogin())
        hashCode = hashCode * 8191 + login.hashCode();

      hashCode = hashCode * 8191 + ((isSetNamespaceName()) ? 131071 : 524287);
      if (isSetNamespaceName())
        hashCode = hashCode * 8191 + namespaceName.hashCode();

      hashCode = hashCode * 8191 + id;

      return hashCode;
    }

    @Override
    public int compareTo(removeNamespaceConstraint_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLogin()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetNamespaceName()).compareTo(other.isSetNamespaceName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetNamespaceName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.namespaceName, other.namespaceName);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetId()).compareTo(other.isSetId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.id, other.id);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("removeNamespaceConstraint_args(");
      boolean first = true;

      sb.append("login:");
      if (this.login == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.login, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("namespaceName:");
      if (this.namespaceName == null) {
        sb.append("null");
      } else {
        sb.append(this.namespaceName);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("id:");
      sb.append(this.id);
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, 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;
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class removeNamespaceConstraint_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public removeNamespaceConstraint_argsStandardScheme getScheme() {
        return new removeNamespaceConstraint_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // LOGIN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.login = iprot.readBinary();
                struct.setLoginIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // NAMESPACE_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.namespaceName = iprot.readString();
                struct.setNamespaceNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ID
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.id = iprot.readI32();
                struct.setIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, removeNamespaceConstraint_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.login != null) {
          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
          oprot.writeBinary(struct.login);
          oprot.writeFieldEnd();
        }
        if (struct.namespaceName != null) {
          oprot.writeFieldBegin(NAMESPACE_NAME_FIELD_DESC);
          oprot.writeString(struct.namespaceName);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldBegin(ID_FIELD_DESC);
        oprot.writeI32(struct.id);
        oprot.writeFieldEnd();
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class removeNamespaceConstraint_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public removeNamespaceConstraint_argsTupleScheme getScheme() {
        return new removeNamespaceConstraint_argsTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetNamespaceName()) {
          optionals.set(1);
        }
        if (struct.isSetId()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetLogin()) {
          oprot.writeBinary(struct.login);
        }
        if (struct.isSetNamespaceName()) {
          oprot.writeString(struct.namespaceName);
        }
        if (struct.isSetId()) {
          oprot.writeI32(struct.id);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, removeNamespaceConstraint_args struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.namespaceName = iprot.readString();
          struct.setNamespaceNameIsSet(true);
        }
        if (incoming.get(2)) {
          struct.id = iprot.readI32();
          struct.setIdIsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("removeNamespaceConstraint_result");

    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField OUCH3_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch3", org.apache.thrift.protocol.TType.STRUCT, (short)3);

    private static final 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
    public NamespaceNotFoundException ouch3; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      OUCH1((short)1, "ouch1"),
      OUCH2((short)2, "ouch2"),
      OUCH3((short)3, "ouch3");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // OUCH1
            return OUCH1;
          case 2: // OUCH2
            return OUCH2;
          case 3: // OUCH3
            return OUCH3;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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.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.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);
    }

    public removeNamespaceConstraint_result() {
    }

    public removeNamespaceConstraint_result(
      AccumuloException ouch1,
      AccumuloSecurityException ouch2,
      NamespaceNotFoundException ouch3)
    {
      this();
      this.ouch1 = ouch1;
      this.ouch2 = ouch2;
      this.ouch3 = ouch3;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public removeNamespaceConstraint_result(removeNamespaceConstraint_result other) {
      if (other.isSetOuch1()) {
        this.ouch1 = new AccumuloException(other.ouch1);
      }
      if (other.isSetOuch2()) {
        this.ouch2 = new AccumuloSecurityException(other.ouch2);
      }
      if (other.isSetOuch3()) {
        this.ouch3 = new NamespaceNotFoundException(other.ouch3);
      }
    }

    public removeNamespaceConstraint_result deepCopy() {
      return new removeNamespaceConstraint_result(this);
    }

    @Override
    public void clear() {
      this.ouch1 = null;
      this.ouch2 = null;
      this.ouch3 = null;
    }

    public AccumuloException getOuch1() {
      return this.ouch1;
    }

    public removeNamespaceConstraint_result setOuch1(AccumuloException ouch1) {
      this.ouch1 = ouch1;
      return this;
    }

    public void unsetOuch1() {
      this.ouch1 = null;
    }

    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch1() {
      return this.ouch1 != null;
    }

    public void setOuch1IsSet(boolean value) {
      if (!value) {
        this.ouch1 = null;
      }
    }

    public AccumuloSecurityException getOuch2() {
      return this.ouch2;
    }

    public removeNamespaceConstraint_result setOuch2(AccumuloSecurityException ouch2) {
      this.ouch2 = ouch2;
      return this;
    }

    public void unsetOuch2() {
      this.ouch2 = null;
    }

    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch2() {
      return this.ouch2 != null;
    }

    public void setOuch2IsSet(boolean value) {
      if (!value) {
        this.ouch2 = null;
      }
    }

    public NamespaceNotFoundException getOuch3() {
      return this.ouch3;
    }

    public removeNamespaceConstraint_result setOuch3(NamespaceNotFoundException ouch3) {
      this.ouch3 = ouch3;
      return this;
    }

    public void unsetOuch3() {
      this.ouch3 = null;
    }

    /** Returns true if field ouch3 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch3() {
      return this.ouch3 != null;
    }

    public void setOuch3IsSet(boolean value) {
      if (!value) {
        this.ouch3 = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case OUCH1:
        if (value == null) {
          unsetOuch1();
        } else {
          setOuch1((AccumuloException)value);
        }
        break;

      case OUCH2:
        if (value == null) {
          unsetOuch2();
        } else {
          setOuch2((AccumuloSecurityException)value);
        }
        break;

      case OUCH3:
        if (value == null) {
          unsetOuch3();
        } else {
          setOuch3((NamespaceNotFoundException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case OUCH1:
        return getOuch1();

      case OUCH2:
        return getOuch2();

      case OUCH3:
        return getOuch3();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case OUCH1:
        return isSetOuch1();
      case OUCH2:
        return isSetOuch2();
      case OUCH3:
        return isSetOuch3();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof removeNamespaceConstraint_result)
        return this.equals((removeNamespaceConstraint_result)that);
      return false;
    }

    public boolean equals(removeNamespaceConstraint_result that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_ouch1 = true && this.isSetOuch1();
      boolean that_present_ouch1 = true && that.isSetOuch1();
      if (this_present_ouch1 || that_present_ouch1) {
        if (!(this_present_ouch1 && that_present_ouch1))
          return false;
        if (!this.ouch1.equals(that.ouch1))
          return false;
      }

      boolean this_present_ouch2 = true && this.isSetOuch2();
      boolean that_present_ouch2 = true && that.isSetOuch2();
      if (this_present_ouch2 || that_present_ouch2) {
        if (!(this_present_ouch2 && that_present_ouch2))
          return false;
        if (!this.ouch2.equals(that.ouch2))
          return false;
      }

      boolean this_present_ouch3 = true && this.isSetOuch3();
      boolean that_present_ouch3 = true && that.isSetOuch3();
      if (this_present_ouch3 || that_present_ouch3) {
        if (!(this_present_ouch3 && that_present_ouch3))
          return false;
        if (!this.ouch3.equals(that.ouch3))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
      if (isSetOuch1())
        hashCode = hashCode * 8191 + ouch1.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
      if (isSetOuch2())
        hashCode = hashCode * 8191 + ouch2.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
      if (isSetOuch3())
        hashCode = hashCode * 8191 + ouch3.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(removeNamespaceConstraint_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch1()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch2()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch3()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch3, other.ouch3);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("removeNamespaceConstraint_result(");
      boolean first = true;

      sb.append("ouch1:");
      if (this.ouch1 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch1);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch2:");
      if (this.ouch2 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch2);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch3:");
      if (this.ouch3 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch3);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class removeNamespaceConstraint_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public removeNamespaceConstraint_resultStandardScheme getScheme() {
        return new removeNamespaceConstraint_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // OUCH1
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch1 = new AccumuloException();
                struct.ouch1.read(iprot);
                struct.setOuch1IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OUCH2
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch2 = new AccumuloSecurityException();
                struct.ouch2.read(iprot);
                struct.setOuch2IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // OUCH3
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch3 = new NamespaceNotFoundException();
                struct.ouch3.read(iprot);
                struct.setOuch3IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, removeNamespaceConstraint_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.ouch1 != null) {
          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
          struct.ouch1.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch2 != null) {
          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
          struct.ouch2.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch3 != null) {
          oprot.writeFieldBegin(OUCH3_FIELD_DESC);
          struct.ouch3.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class removeNamespaceConstraint_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public removeNamespaceConstraint_resultTupleScheme getScheme() {
        return new removeNamespaceConstraint_resultTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetOuch2()) {
          optionals.set(1);
        }
        if (struct.isSetOuch3()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetOuch1()) {
          struct.ouch1.write(oprot);
        }
        if (struct.isSetOuch2()) {
          struct.ouch2.write(oprot);
        }
        if (struct.isSetOuch3()) {
          struct.ouch3.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, removeNamespaceConstraint_result struct) throws org.apache.thrift.TException {
        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);
          struct.setOuch1IsSet(true);
        }
        if (incoming.get(1)) {
          struct.ouch2 = new AccumuloSecurityException();
          struct.ouch2.read(iprot);
          struct.setOuch2IsSet(true);
        }
        if (incoming.get(2)) {
          struct.ouch3 = new NamespaceNotFoundException();
          struct.ouch3.read(iprot);
          struct.setOuch3IsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("listNamespaceConstraints_args");

    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField NAMESPACE_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("namespaceName", org.apache.thrift.protocol.TType.STRING, (short)2);

    private static final 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 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 java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // LOGIN
            return LOGIN;
          case 2: // NAMESPACE_NAME
            return NAMESPACE_NAME;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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 = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(listNamespaceConstraints_args.class, metaDataMap);
    }

    public listNamespaceConstraints_args() {
    }

    public listNamespaceConstraints_args(
      java.nio.ByteBuffer login,
      java.lang.String namespaceName)
    {
      this();
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      this.namespaceName = namespaceName;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public listNamespaceConstraints_args(listNamespaceConstraints_args other) {
      if (other.isSetLogin()) {
        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
      }
      if (other.isSetNamespaceName()) {
        this.namespaceName = other.namespaceName;
      }
    }

    public listNamespaceConstraints_args deepCopy() {
      return new listNamespaceConstraints_args(this);
    }

    @Override
    public void clear() {
      this.login = null;
      this.namespaceName = null;
    }

    public byte[] getLogin() {
      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
      return login == null ? null : login.array();
    }

    public java.nio.ByteBuffer bufferForLogin() {
      return org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    public listNamespaceConstraints_args setLogin(byte[] login) {
      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
      return this;
    }

    public listNamespaceConstraints_args setLogin(java.nio.ByteBuffer login) {
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      return this;
    }

    public void unsetLogin() {
      this.login = null;
    }

    /** Returns true if field login is set (has been assigned a value) and false otherwise */
    public boolean isSetLogin() {
      return this.login != null;
    }

    public void setLoginIsSet(boolean value) {
      if (!value) {
        this.login = null;
      }
    }

    public java.lang.String getNamespaceName() {
      return this.namespaceName;
    }

    public listNamespaceConstraints_args setNamespaceName(java.lang.String namespaceName) {
      this.namespaceName = namespaceName;
      return this;
    }

    public void unsetNamespaceName() {
      this.namespaceName = null;
    }

    /** Returns true if field namespaceName is set (has been assigned a value) and false otherwise */
    public boolean isSetNamespaceName() {
      return this.namespaceName != null;
    }

    public void setNamespaceNameIsSet(boolean value) {
      if (!value) {
        this.namespaceName = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case LOGIN:
        if (value == null) {
          unsetLogin();
        } else {
          if (value instanceof byte[]) {
            setLogin((byte[])value);
          } else {
            setLogin((java.nio.ByteBuffer)value);
          }
        }
        break;

      case NAMESPACE_NAME:
        if (value == null) {
          unsetNamespaceName();
        } else {
          setNamespaceName((java.lang.String)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case LOGIN:
        return getLogin();

      case NAMESPACE_NAME:
        return getNamespaceName();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case LOGIN:
        return isSetLogin();
      case NAMESPACE_NAME:
        return isSetNamespaceName();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof listNamespaceConstraints_args)
        return this.equals((listNamespaceConstraints_args)that);
      return false;
    }

    public boolean equals(listNamespaceConstraints_args that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_login = true && this.isSetLogin();
      boolean that_present_login = true && that.isSetLogin();
      if (this_present_login || that_present_login) {
        if (!(this_present_login && that_present_login))
          return false;
        if (!this.login.equals(that.login))
          return false;
      }

      boolean this_present_namespaceName = true && this.isSetNamespaceName();
      boolean that_present_namespaceName = true && that.isSetNamespaceName();
      if (this_present_namespaceName || that_present_namespaceName) {
        if (!(this_present_namespaceName && that_present_namespaceName))
          return false;
        if (!this.namespaceName.equals(that.namespaceName))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
      if (isSetLogin())
        hashCode = hashCode * 8191 + login.hashCode();

      hashCode = hashCode * 8191 + ((isSetNamespaceName()) ? 131071 : 524287);
      if (isSetNamespaceName())
        hashCode = hashCode * 8191 + namespaceName.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(listNamespaceConstraints_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLogin()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetNamespaceName()).compareTo(other.isSetNamespaceName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetNamespaceName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.namespaceName, other.namespaceName);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("listNamespaceConstraints_args(");
      boolean first = true;

      sb.append("login:");
      if (this.login == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.login, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("namespaceName:");
      if (this.namespaceName == null) {
        sb.append("null");
      } else {
        sb.append(this.namespaceName);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class listNamespaceConstraints_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public listNamespaceConstraints_argsStandardScheme getScheme() {
        return new listNamespaceConstraints_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // LOGIN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.login = iprot.readBinary();
                struct.setLoginIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // NAMESPACE_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.namespaceName = iprot.readString();
                struct.setNamespaceNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, listNamespaceConstraints_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.login != null) {
          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
          oprot.writeBinary(struct.login);
          oprot.writeFieldEnd();
        }
        if (struct.namespaceName != null) {
          oprot.writeFieldBegin(NAMESPACE_NAME_FIELD_DESC);
          oprot.writeString(struct.namespaceName);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class listNamespaceConstraints_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public listNamespaceConstraints_argsTupleScheme getScheme() {
        return new listNamespaceConstraints_argsTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetNamespaceName()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetLogin()) {
          oprot.writeBinary(struct.login);
        }
        if (struct.isSetNamespaceName()) {
          oprot.writeString(struct.namespaceName);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, listNamespaceConstraints_args struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.namespaceName = iprot.readString();
          struct.setNamespaceNameIsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("listNamespaceConstraints_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.MAP, (short)0);
    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField OUCH3_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch3", org.apache.thrift.protocol.TType.STRUCT, (short)3);

    private static final 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 java.util.Map<java.lang.String,java.lang.Integer> success; // required
    public AccumuloException ouch1; // required
    public AccumuloSecurityException ouch2; // required
    public NamespaceNotFoundException ouch3; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      OUCH1((short)1, "ouch1"),
      OUCH2((short)2, "ouch2"),
      OUCH3((short)3, "ouch3");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // OUCH1
            return OUCH1;
          case 2: // OUCH2
            return OUCH2;
          case 3: // OUCH3
            return OUCH3;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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.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.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);
    }

    public listNamespaceConstraints_result() {
    }

    public listNamespaceConstraints_result(
      java.util.Map<java.lang.String,java.lang.Integer> success,
      AccumuloException ouch1,
      AccumuloSecurityException ouch2,
      NamespaceNotFoundException ouch3)
    {
      this();
      this.success = success;
      this.ouch1 = ouch1;
      this.ouch2 = ouch2;
      this.ouch3 = ouch3;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public listNamespaceConstraints_result(listNamespaceConstraints_result other) {
      if (other.isSetSuccess()) {
        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()) {
        this.ouch1 = new AccumuloException(other.ouch1);
      }
      if (other.isSetOuch2()) {
        this.ouch2 = new AccumuloSecurityException(other.ouch2);
      }
      if (other.isSetOuch3()) {
        this.ouch3 = new NamespaceNotFoundException(other.ouch3);
      }
    }

    public listNamespaceConstraints_result deepCopy() {
      return new listNamespaceConstraints_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ouch1 = null;
      this.ouch2 = null;
      this.ouch3 = null;
    }

    public int getSuccessSize() {
      return (this.success == null) ? 0 : this.success.size();
    }

    public void putToSuccess(java.lang.String key, int val) {
      if (this.success == null) {
        this.success = new java.util.HashMap<java.lang.String,java.lang.Integer>();
      }
      this.success.put(key, val);
    }

    public java.util.Map<java.lang.String,java.lang.Integer> getSuccess() {
      return this.success;
    }

    public listNamespaceConstraints_result setSuccess(java.util.Map<java.lang.String,java.lang.Integer> success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return this.success != null;
    }

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public AccumuloException getOuch1() {
      return this.ouch1;
    }

    public listNamespaceConstraints_result setOuch1(AccumuloException ouch1) {
      this.ouch1 = ouch1;
      return this;
    }

    public void unsetOuch1() {
      this.ouch1 = null;
    }

    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch1() {
      return this.ouch1 != null;
    }

    public void setOuch1IsSet(boolean value) {
      if (!value) {
        this.ouch1 = null;
      }
    }

    public AccumuloSecurityException getOuch2() {
      return this.ouch2;
    }

    public listNamespaceConstraints_result setOuch2(AccumuloSecurityException ouch2) {
      this.ouch2 = ouch2;
      return this;
    }

    public void unsetOuch2() {
      this.ouch2 = null;
    }

    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch2() {
      return this.ouch2 != null;
    }

    public void setOuch2IsSet(boolean value) {
      if (!value) {
        this.ouch2 = null;
      }
    }

    public NamespaceNotFoundException getOuch3() {
      return this.ouch3;
    }

    public listNamespaceConstraints_result setOuch3(NamespaceNotFoundException ouch3) {
      this.ouch3 = ouch3;
      return this;
    }

    public void unsetOuch3() {
      this.ouch3 = null;
    }

    /** Returns true if field ouch3 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch3() {
      return this.ouch3 != null;
    }

    public void setOuch3IsSet(boolean value) {
      if (!value) {
        this.ouch3 = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.util.Map<java.lang.String,java.lang.Integer>)value);
        }
        break;

      case OUCH1:
        if (value == null) {
          unsetOuch1();
        } else {
          setOuch1((AccumuloException)value);
        }
        break;

      case OUCH2:
        if (value == null) {
          unsetOuch2();
        } else {
          setOuch2((AccumuloSecurityException)value);
        }
        break;

      case OUCH3:
        if (value == null) {
          unsetOuch3();
        } else {
          setOuch3((NamespaceNotFoundException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case OUCH1:
        return getOuch1();

      case OUCH2:
        return getOuch2();

      case OUCH3:
        return getOuch3();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case OUCH1:
        return isSetOuch1();
      case OUCH2:
        return isSetOuch2();
      case OUCH3:
        return isSetOuch3();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof listNamespaceConstraints_result)
        return this.equals((listNamespaceConstraints_result)that);
      return false;
    }

    public boolean equals(listNamespaceConstraints_result that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ouch1 = true && this.isSetOuch1();
      boolean that_present_ouch1 = true && that.isSetOuch1();
      if (this_present_ouch1 || that_present_ouch1) {
        if (!(this_present_ouch1 && that_present_ouch1))
          return false;
        if (!this.ouch1.equals(that.ouch1))
          return false;
      }

      boolean this_present_ouch2 = true && this.isSetOuch2();
      boolean that_present_ouch2 = true && that.isSetOuch2();
      if (this_present_ouch2 || that_present_ouch2) {
        if (!(this_present_ouch2 && that_present_ouch2))
          return false;
        if (!this.ouch2.equals(that.ouch2))
          return false;
      }

      boolean this_present_ouch3 = true && this.isSetOuch3();
      boolean that_present_ouch3 = true && that.isSetOuch3();
      if (this_present_ouch3 || that_present_ouch3) {
        if (!(this_present_ouch3 && that_present_ouch3))
          return false;
        if (!this.ouch3.equals(that.ouch3))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
      if (isSetSuccess())
        hashCode = hashCode * 8191 + success.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
      if (isSetOuch1())
        hashCode = hashCode * 8191 + ouch1.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
      if (isSetOuch2())
        hashCode = hashCode * 8191 + ouch2.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
      if (isSetOuch3())
        hashCode = hashCode * 8191 + ouch3.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(listNamespaceConstraints_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch1()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch2()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch3()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch3, other.ouch3);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("listNamespaceConstraints_result(");
      boolean first = true;

      sb.append("success:");
      if (this.success == null) {
        sb.append("null");
      } else {
        sb.append(this.success);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch1:");
      if (this.ouch1 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch1);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch2:");
      if (this.ouch2 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch2);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch3:");
      if (this.ouch3 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch3);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class listNamespaceConstraints_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public listNamespaceConstraints_resultStandardScheme getScheme() {
        return new listNamespaceConstraints_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.MAP) {
                {
                  org.apache.thrift.protocol.TMap _map568 = iprot.readMapBegin();
                  struct.success = new 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)
                  {
                    _key569 = iprot.readString();
                    _val570 = iprot.readI32();
                    struct.success.put(_key569, _val570);
                  }
                  iprot.readMapEnd();
                }
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // OUCH1
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch1 = new AccumuloException();
                struct.ouch1.read(iprot);
                struct.setOuch1IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OUCH2
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch2 = new AccumuloSecurityException();
                struct.ouch2.read(iprot);
                struct.setOuch2IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // OUCH3
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch3 = new NamespaceNotFoundException();
                struct.ouch3.read(iprot);
                struct.setOuch3IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, listNamespaceConstraints_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          {
            oprot.writeMapBegin(new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.I32, struct.success.size()));
            for (java.util.Map.Entry<java.lang.String, java.lang.Integer> _iter572 : struct.success.entrySet())
            {
              oprot.writeString(_iter572.getKey());
              oprot.writeI32(_iter572.getValue());
            }
            oprot.writeMapEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.ouch1 != null) {
          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
          struct.ouch1.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch2 != null) {
          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
          struct.ouch2.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch3 != null) {
          oprot.writeFieldBegin(OUCH3_FIELD_DESC);
          struct.ouch3.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class listNamespaceConstraints_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public listNamespaceConstraints_resultTupleScheme getScheme() {
        return new listNamespaceConstraints_resultTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetOuch1()) {
          optionals.set(1);
        }
        if (struct.isSetOuch2()) {
          optionals.set(2);
        }
        if (struct.isSetOuch3()) {
          optionals.set(3);
        }
        oprot.writeBitSet(optionals, 4);
        if (struct.isSetSuccess()) {
          {
            oprot.writeI32(struct.success.size());
            for (java.util.Map.Entry<java.lang.String, java.lang.Integer> _iter573 : struct.success.entrySet())
            {
              oprot.writeString(_iter573.getKey());
              oprot.writeI32(_iter573.getValue());
            }
          }
        }
        if (struct.isSetOuch1()) {
          struct.ouch1.write(oprot);
        }
        if (struct.isSetOuch2()) {
          struct.ouch2.write(oprot);
        }
        if (struct.isSetOuch3()) {
          struct.ouch3.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, listNamespaceConstraints_result struct) throws org.apache.thrift.TException {
        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 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)
            {
              _key575 = iprot.readString();
              _val576 = iprot.readI32();
              struct.success.put(_key575, _val576);
            }
          }
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ouch1 = new AccumuloException();
          struct.ouch1.read(iprot);
          struct.setOuch1IsSet(true);
        }
        if (incoming.get(2)) {
          struct.ouch2 = new AccumuloSecurityException();
          struct.ouch2.read(iprot);
          struct.setOuch2IsSet(true);
        }
        if (incoming.get(3)) {
          struct.ouch3 = new NamespaceNotFoundException();
          struct.ouch3.read(iprot);
          struct.setOuch3IsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("testNamespaceClassLoad_args");

    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField NAMESPACE_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("namespaceName", org.apache.thrift.protocol.TType.STRING, (short)2);
    private static final org.apache.thrift.protocol.TField CLASS_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("className", org.apache.thrift.protocol.TType.STRING, (short)3);
    private static final org.apache.thrift.protocol.TField AS_TYPE_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("asTypeName", org.apache.thrift.protocol.TType.STRING, (short)4);

    private static final 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 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 {
      LOGIN((short)1, "login"),
      NAMESPACE_NAME((short)2, "namespaceName"),
      CLASS_NAME((short)3, "className"),
      AS_TYPE_NAME((short)4, "asTypeName");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // LOGIN
            return LOGIN;
          case 2: // NAMESPACE_NAME
            return NAMESPACE_NAME;
          case 3: // CLASS_NAME
            return CLASS_NAME;
          case 4: // AS_TYPE_NAME
            return AS_TYPE_NAME;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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 = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(testNamespaceClassLoad_args.class, metaDataMap);
    }

    public testNamespaceClassLoad_args() {
    }

    public testNamespaceClassLoad_args(
      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);
      this.namespaceName = namespaceName;
      this.className = className;
      this.asTypeName = asTypeName;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public testNamespaceClassLoad_args(testNamespaceClassLoad_args other) {
      if (other.isSetLogin()) {
        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
      }
      if (other.isSetNamespaceName()) {
        this.namespaceName = other.namespaceName;
      }
      if (other.isSetClassName()) {
        this.className = other.className;
      }
      if (other.isSetAsTypeName()) {
        this.asTypeName = other.asTypeName;
      }
    }

    public testNamespaceClassLoad_args deepCopy() {
      return new testNamespaceClassLoad_args(this);
    }

    @Override
    public void clear() {
      this.login = null;
      this.namespaceName = null;
      this.className = null;
      this.asTypeName = null;
    }

    public byte[] getLogin() {
      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
      return login == null ? null : login.array();
    }

    public java.nio.ByteBuffer bufferForLogin() {
      return org.apache.thrift.TBaseHelper.copyBinary(login);
    }

    public testNamespaceClassLoad_args setLogin(byte[] login) {
      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
      return this;
    }

    public testNamespaceClassLoad_args setLogin(java.nio.ByteBuffer login) {
      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
      return this;
    }

    public void unsetLogin() {
      this.login = null;
    }

    /** Returns true if field login is set (has been assigned a value) and false otherwise */
    public boolean isSetLogin() {
      return this.login != null;
    }

    public void setLoginIsSet(boolean value) {
      if (!value) {
        this.login = null;
      }
    }

    public java.lang.String getNamespaceName() {
      return this.namespaceName;
    }

    public testNamespaceClassLoad_args setNamespaceName(java.lang.String namespaceName) {
      this.namespaceName = namespaceName;
      return this;
    }

    public void unsetNamespaceName() {
      this.namespaceName = null;
    }

    /** Returns true if field namespaceName is set (has been assigned a value) and false otherwise */
    public boolean isSetNamespaceName() {
      return this.namespaceName != null;
    }

    public void setNamespaceNameIsSet(boolean value) {
      if (!value) {
        this.namespaceName = null;
      }
    }

    public java.lang.String getClassName() {
      return this.className;
    }

    public testNamespaceClassLoad_args setClassName(java.lang.String className) {
      this.className = className;
      return this;
    }

    public void unsetClassName() {
      this.className = null;
    }

    /** Returns true if field className is set (has been assigned a value) and false otherwise */
    public boolean isSetClassName() {
      return this.className != null;
    }

    public void setClassNameIsSet(boolean value) {
      if (!value) {
        this.className = null;
      }
    }

    public java.lang.String getAsTypeName() {
      return this.asTypeName;
    }

    public testNamespaceClassLoad_args setAsTypeName(java.lang.String asTypeName) {
      this.asTypeName = asTypeName;
      return this;
    }

    public void unsetAsTypeName() {
      this.asTypeName = null;
    }

    /** Returns true if field asTypeName is set (has been assigned a value) and false otherwise */
    public boolean isSetAsTypeName() {
      return this.asTypeName != null;
    }

    public void setAsTypeNameIsSet(boolean value) {
      if (!value) {
        this.asTypeName = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case LOGIN:
        if (value == null) {
          unsetLogin();
        } else {
          if (value instanceof byte[]) {
            setLogin((byte[])value);
          } else {
            setLogin((java.nio.ByteBuffer)value);
          }
        }
        break;

      case NAMESPACE_NAME:
        if (value == null) {
          unsetNamespaceName();
        } else {
          setNamespaceName((java.lang.String)value);
        }
        break;

      case CLASS_NAME:
        if (value == null) {
          unsetClassName();
        } else {
          setClassName((java.lang.String)value);
        }
        break;

      case AS_TYPE_NAME:
        if (value == null) {
          unsetAsTypeName();
        } else {
          setAsTypeName((java.lang.String)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case LOGIN:
        return getLogin();

      case NAMESPACE_NAME:
        return getNamespaceName();

      case CLASS_NAME:
        return getClassName();

      case AS_TYPE_NAME:
        return getAsTypeName();

      }
      throw new 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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case LOGIN:
        return isSetLogin();
      case NAMESPACE_NAME:
        return isSetNamespaceName();
      case CLASS_NAME:
        return isSetClassName();
      case AS_TYPE_NAME:
        return isSetAsTypeName();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof testNamespaceClassLoad_args)
        return this.equals((testNamespaceClassLoad_args)that);
      return false;
    }

    public boolean equals(testNamespaceClassLoad_args that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_login = true && this.isSetLogin();
      boolean that_present_login = true && that.isSetLogin();
      if (this_present_login || that_present_login) {
        if (!(this_present_login && that_present_login))
          return false;
        if (!this.login.equals(that.login))
          return false;
      }

      boolean this_present_namespaceName = true && this.isSetNamespaceName();
      boolean that_present_namespaceName = true && that.isSetNamespaceName();
      if (this_present_namespaceName || that_present_namespaceName) {
        if (!(this_present_namespaceName && that_present_namespaceName))
          return false;
        if (!this.namespaceName.equals(that.namespaceName))
          return false;
      }

      boolean this_present_className = true && this.isSetClassName();
      boolean that_present_className = true && that.isSetClassName();
      if (this_present_className || that_present_className) {
        if (!(this_present_className && that_present_className))
          return false;
        if (!this.className.equals(that.className))
          return false;
      }

      boolean this_present_asTypeName = true && this.isSetAsTypeName();
      boolean that_present_asTypeName = true && that.isSetAsTypeName();
      if (this_present_asTypeName || that_present_asTypeName) {
        if (!(this_present_asTypeName && that_present_asTypeName))
          return false;
        if (!this.asTypeName.equals(that.asTypeName))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
      if (isSetLogin())
        hashCode = hashCode * 8191 + login.hashCode();

      hashCode = hashCode * 8191 + ((isSetNamespaceName()) ? 131071 : 524287);
      if (isSetNamespaceName())
        hashCode = hashCode * 8191 + namespaceName.hashCode();

      hashCode = hashCode * 8191 + ((isSetClassName()) ? 131071 : 524287);
      if (isSetClassName())
        hashCode = hashCode * 8191 + className.hashCode();

      hashCode = hashCode * 8191 + ((isSetAsTypeName()) ? 131071 : 524287);
      if (isSetAsTypeName())
        hashCode = hashCode * 8191 + asTypeName.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(testNamespaceClassLoad_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLogin()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetNamespaceName()).compareTo(other.isSetNamespaceName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetNamespaceName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.namespaceName, other.namespaceName);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetClassName()).compareTo(other.isSetClassName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetClassName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.className, other.className);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetAsTypeName()).compareTo(other.isSetAsTypeName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAsTypeName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.asTypeName, other.asTypeName);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("testNamespaceClassLoad_args(");
      boolean first = true;

      sb.append("login:");
      if (this.login == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.login, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("namespaceName:");
      if (this.namespaceName == null) {
        sb.append("null");
      } else {
        sb.append(this.namespaceName);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("className:");
      if (this.className == null) {
        sb.append("null");
      } else {
        sb.append(this.className);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("asTypeName:");
      if (this.asTypeName == null) {
        sb.append("null");
      } else {
        sb.append(this.asTypeName);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class testNamespaceClassLoad_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public testNamespaceClassLoad_argsStandardScheme getScheme() {
        return new testNamespaceClassLoad_argsStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // LOGIN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.login = iprot.readBinary();
                struct.setLoginIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // NAMESPACE_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.namespaceName = iprot.readString();
                struct.setNamespaceNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // CLASS_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.className = iprot.readString();
                struct.setClassNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // AS_TYPE_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.asTypeName = iprot.readString();
                struct.setAsTypeNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, testNamespaceClassLoad_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.login != null) {
          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
          oprot.writeBinary(struct.login);
          oprot.writeFieldEnd();
        }
        if (struct.namespaceName != null) {
          oprot.writeFieldBegin(NAMESPACE_NAME_FIELD_DESC);
          oprot.writeString(struct.namespaceName);
          oprot.writeFieldEnd();
        }
        if (struct.className != null) {
          oprot.writeFieldBegin(CLASS_NAME_FIELD_DESC);
          oprot.writeString(struct.className);
          oprot.writeFieldEnd();
        }
        if (struct.asTypeName != null) {
          oprot.writeFieldBegin(AS_TYPE_NAME_FIELD_DESC);
          oprot.writeString(struct.asTypeName);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class testNamespaceClassLoad_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public testNamespaceClassLoad_argsTupleScheme getScheme() {
        return new testNamespaceClassLoad_argsTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetNamespaceName()) {
          optionals.set(1);
        }
        if (struct.isSetClassName()) {
          optionals.set(2);
        }
        if (struct.isSetAsTypeName()) {
          optionals.set(3);
        }
        oprot.writeBitSet(optionals, 4);
        if (struct.isSetLogin()) {
          oprot.writeBinary(struct.login);
        }
        if (struct.isSetNamespaceName()) {
          oprot.writeString(struct.namespaceName);
        }
        if (struct.isSetClassName()) {
          oprot.writeString(struct.className);
        }
        if (struct.isSetAsTypeName()) {
          oprot.writeString(struct.asTypeName);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, testNamespaceClassLoad_args struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.namespaceName = iprot.readString();
          struct.setNamespaceNameIsSet(true);
        }
        if (incoming.get(2)) {
          struct.className = iprot.readString();
          struct.setClassNameIsSet(true);
        }
        if (incoming.get(3)) {
          struct.asTypeName = iprot.readString();
          struct.setAsTypeNameIsSet(true);
        }
      }
    }

    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>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("testNamespaceClassLoad_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.BOOL, (short)0);
    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField OUCH3_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch3", org.apache.thrift.protocol.TType.STRUCT, (short)3);

    private static final 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
    public AccumuloSecurityException ouch2; // required
    public NamespaceNotFoundException ouch3; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      OUCH1((short)1, "ouch1"),
      OUCH2((short)2, "ouch2"),
      OUCH3((short)3, "ouch3");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // OUCH1
            return OUCH1;
          case 2: // OUCH2
            return OUCH2;
          case 3: // OUCH3
            return OUCH3;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new 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(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __SUCCESS_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      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.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.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.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);
    }

    public testNamespaceClassLoad_result() {
    }

    public testNamespaceClassLoad_result(
      boolean success,
      AccumuloException ouch1,
      AccumuloSecurityException ouch2,
      NamespaceNotFoundException ouch3)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
      this.ouch1 = ouch1;
      this.ouch2 = ouch2;
      this.ouch3 = ouch3;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public testNamespaceClassLoad_result(testNamespaceClassLoad_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
      if (other.isSetOuch1()) {
        this.ouch1 = new AccumuloException(other.ouch1);
      }
      if (other.isSetOuch2()) {
        this.ouch2 = new AccumuloSecurityException(other.ouch2);
      }
      if (other.isSetOuch3()) {
        this.ouch3 = new NamespaceNotFoundException(other.ouch3);
      }
    }

    public testNamespaceClassLoad_result deepCopy() {
      return new testNamespaceClassLoad_result(this);
    }

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
      this.ouch1 = null;
      this.ouch2 = null;
      this.ouch3 = null;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public testNamespaceClassLoad_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

    public void unsetSuccess() {
      __isset_bitfield = 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 org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    public void setSuccessIsSet(boolean value) {
      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
    }

    public AccumuloException getOuch1() {
      return this.ouch1;
    }

    public testNamespaceClassLoad_result setOuch1(AccumuloException ouch1) {
      this.ouch1 = ouch1;
      return this;
    }

    public void unsetOuch1() {
      this.ouch1 = null;
    }

    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch1() {
      return this.ouch1 != null;
    }

    public void setOuch1IsSet(boolean value) {
      if (!value) {
        this.ouch1 = null;
      }
    }

    public AccumuloSecurityException getOuch2() {
      return this.ouch2;
    }

    public testNamespaceClassLoad_result setOuch2(AccumuloSecurityException ouch2) {
      this.ouch2 = ouch2;
      return this;
    }

    public void unsetOuch2() {
      this.ouch2 = null;
    }

    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch2() {
      return this.ouch2 != null;
    }

    public void setOuch2IsSet(boolean value) {
      if (!value) {
        this.ouch2 = null;
      }
    }

    public NamespaceNotFoundException getOuch3() {
      return this.ouch3;
    }

    public testNamespaceClassLoad_result setOuch3(NamespaceNotFoundException ouch3) {
      this.ouch3 = ouch3;
      return this;
    }

    public void unsetOuch3() {
      this.ouch3 = null;
    }

    /** Returns true if field ouch3 is set (has been assigned a value) and false otherwise */
    public boolean isSetOuch3() {
      return this.ouch3 != null;
    }

    public void setOuch3IsSet(boolean value) {
      if (!value) {
        this.ouch3 = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.lang.Boolean)value);
        }
        break;

      case OUCH1:
        if (value == null) {
          unsetOuch1();
        } else {
          setOuch1((AccumuloException)value);
        }
        break;

      case OUCH2:
        if (value == null) {
          unsetOuch2();
        } else {
          setOuch2((AccumuloSecurityException)value);
        }
        break;

      case OUCH3:
        if (value == null) {
          unsetOuch3();
        } else {
          setOuch3((NamespaceNotFoundException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return isSuccess();

      case OUCH1:
        return getOuch1();

      case OUCH2:
        return getOuch2();

      case OUCH3:
        return getOuch3();

      }
      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 java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case OUCH1:
        return isSetOuch1();
      case OUCH2:
        return isSetOuch2();
      case OUCH3:
        return isSetOuch3();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof testNamespaceClassLoad_result)
        return this.equals((testNamespaceClassLoad_result)that);
      return false;
    }

    public boolean equals(testNamespaceClassLoad_result that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_success = true;
      boolean that_present_success = true;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      boolean this_present_ouch1 = true && this.isSetOuch1();
      boolean that_present_ouch1 = true && that.isSetOuch1();
      if (this_present_ouch1 || that_present_ouch1) {
        if (!(this_present_ouch1 && that_present_ouch1))
          return false;
        if (!this.ouch1.equals(that.ouch1))
          return false;
      }

      boolean this_present_ouch2 = true && this.isSetOuch2();
      boolean that_present_ouch2 = true && that.isSetOuch2();
      if (this_present_ouch2 || that_present_ouch2) {
        if (!(this_present_ouch2 && that_present_ouch2))
          return false;
        if (!this.ouch2.equals(that.ouch2))
          return false;
      }

      boolean this_present_ouch3 = true && this.isSetOuch3();
      boolean that_present_ouch3 = true && that.isSetOuch3();
      if (this_present_ouch3 || that_present_ouch3) {
        if (!(this_present_ouch3 && that_present_ouch3))
          return false;
        if (!this.ouch3.equals(that.ouch3))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((success) ? 131071 : 524287);

      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
      if (isSetOuch1())
        hashCode = hashCode * 8191 + ouch1.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
      if (isSetOuch2())
        hashCode = hashCode * 8191 + ouch2.hashCode();

      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
      if (isSetOuch3())
        hashCode = hashCode * 8191 + ouch3.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(testNamespaceClassLoad_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch1()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch2()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOuch3()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch3, other.ouch3);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("testNamespaceClassLoad_result(");
      boolean first = true;

      sb.append("success:");
      sb.append(this.success);
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch1:");
      if (this.ouch1 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch1);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch2:");
      if (this.ouch2 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch2);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ouch3:");
      if (this.ouch3 == null) {
        sb.append("null");
      } else {
        sb.append(this.ouch3);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, 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;
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class testNamespaceClassLoad_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public testNamespaceClassLoad_resultStandardScheme getScheme() {
        return new testNamespaceClassLoad_resultStandardScheme();
      }
    }

    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;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
                struct.success = iprot.readBool();
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // OUCH1
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch1 = new AccumuloException();
                struct.ouch1.read(iprot);
                struct.setOuch1IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OUCH2
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch2 = new AccumuloSecurityException();
                struct.ouch2.read(iprot);
                struct.setOuch2IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // OUCH3
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ouch3 = new NamespaceNotFoundException();
                struct.ouch3.read(iprot);
                struct.setOuch3IsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, testNamespaceClassLoad_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.isSetSuccess()) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          oprot.writeBool(struct.success);
          oprot.writeFieldEnd();
        }
        if (struct.ouch1 != null) {
          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
          struct.ouch1.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch2 != null) {
          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
          struct.ouch2.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ouch3 != null) {
          oprot.writeFieldBegin(OUCH3_FIELD_DESC);
          struct.ouch3.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class testNamespaceClassLoad_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public testNamespaceClassLoad_resultTupleScheme getScheme() {
        return new testNamespaceClassLoad_resultTupleScheme();
      }
    }

    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 {
        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);
        }
        if (struct.isSetOuch1()) {
          optionals.set(1);
        }
        if (struct.isSetOuch2()) {
          optionals.set(2);
        }
        if (struct.isSetOuch3()) {
          optionals.set(3);
        }
        oprot.writeBitSet(optionals, 4);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
        if (struct.isSetOuch1()) {
          struct.ouch1.write(oprot);
        }
        if (struct.isSetOuch2()) {
          struct.ouch2.write(oprot);
        }
        if (struct.isSetOuch3()) {
          struct.ouch3.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, testNamespaceClassLoad_result struct) throws org.apache.thrift.TException {
        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);
        }
        if (incoming.get(1)) {
          struct.ouch1 = new AccumuloException();
          struct.ouch1.read(iprot);
          struct.setOuch1IsSet(true);
        }
        if (incoming.get(2)) {
          struct.ouch2 = new AccumuloSecurityException();
          struct.ouch2.read(iprot);
          struct.setOuch2IsSet(true);
        }
        if (incoming.get(3)) {
          struct.ouch3 = new NamespaceNotFoundException();
          struct.ouch3.read(iprot);
          struct.setOuch3IsSet(true);
        }
      }
    }

    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() {}
}
