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

#include <thrift/TDispatchProcessor.h>
#include <thrift/async/TConcurrentClientSyncInfo.h>
#include "proxy_types.h"

namespace accumulo {

#ifdef _WIN32
  #pragma warning( push )
  #pragma warning (disable : 4250 ) //inheriting methods via dominance 
#endif

class AccumuloProxyIf {
 public:
  virtual ~AccumuloProxyIf() {}
  virtual void login(std::string& _return, const std::string& principal, const std::map<std::string, std::string> & loginProperties) = 0;
  virtual int32_t addConstraint(const std::string& login, const std::string& tableName, const std::string& constraintClassName) = 0;
  virtual void addSplits(const std::string& login, const std::string& tableName, const std::set<std::string> & splits) = 0;
  virtual void attachIterator(const std::string& login, const std::string& tableName, const IteratorSetting& setting, const std::set<IteratorScope::type> & scopes) = 0;
  virtual void checkIteratorConflicts(const std::string& login, const std::string& tableName, const IteratorSetting& setting, const std::set<IteratorScope::type> & scopes) = 0;
  virtual void clearLocatorCache(const std::string& login, const std::string& tableName) = 0;
  virtual void cloneTable(const std::string& login, const std::string& tableName, const std::string& newTableName, const bool flush, const std::map<std::string, std::string> & propertiesToSet, const std::set<std::string> & propertiesToExclude) = 0;
  virtual void compactTable(const std::string& login, const std::string& tableName, const std::string& startRow, const std::string& endRow, const std::vector<IteratorSetting> & iterators, const bool flush, const bool wait, const CompactionStrategyConfig& compactionStrategy) = 0;
  virtual void cancelCompaction(const std::string& login, const std::string& tableName) = 0;
  virtual void createTable(const std::string& login, const std::string& tableName, const bool versioningIter, const TimeType::type type) = 0;
  virtual void deleteTable(const std::string& login, const std::string& tableName) = 0;
  virtual void deleteRows(const std::string& login, const std::string& tableName, const std::string& startRow, const std::string& endRow) = 0;
  virtual void exportTable(const std::string& login, const std::string& tableName, const std::string& exportDir) = 0;
  virtual void flushTable(const std::string& login, const std::string& tableName, const std::string& startRow, const std::string& endRow, const bool wait) = 0;
  virtual void getDiskUsage(std::vector<DiskUsage> & _return, const std::string& login, const std::set<std::string> & tables) = 0;
  virtual void getLocalityGroups(std::map<std::string, std::set<std::string> > & _return, const std::string& login, const std::string& tableName) = 0;
  virtual void getIteratorSetting(IteratorSetting& _return, const std::string& login, const std::string& tableName, const std::string& iteratorName, const IteratorScope::type scope) = 0;
  virtual void getMaxRow(std::string& _return, const std::string& login, const std::string& tableName, const std::set<std::string> & auths, const std::string& startRow, const bool startInclusive, const std::string& endRow, const bool endInclusive) = 0;
  virtual void getTableProperties(std::map<std::string, std::string> & _return, const std::string& login, const std::string& tableName) = 0;
  virtual void importDirectory(const std::string& login, const std::string& tableName, const std::string& importDir, const std::string& failureDir, const bool setTime) = 0;
  virtual void importTable(const std::string& login, const std::string& tableName, const std::string& importDir) = 0;
  virtual void listSplits(std::vector<std::string> & _return, const std::string& login, const std::string& tableName, const int32_t maxSplits) = 0;
  virtual void listTables(std::set<std::string> & _return, const std::string& login) = 0;
  virtual void listIterators(std::map<std::string, std::set<IteratorScope::type> > & _return, const std::string& login, const std::string& tableName) = 0;
  virtual void listConstraints(std::map<std::string, int32_t> & _return, const std::string& login, const std::string& tableName) = 0;
  virtual void mergeTablets(const std::string& login, const std::string& tableName, const std::string& startRow, const std::string& endRow) = 0;
  virtual void offlineTable(const std::string& login, const std::string& tableName, const bool wait) = 0;
  virtual void onlineTable(const std::string& login, const std::string& tableName, const bool wait) = 0;
  virtual void removeConstraint(const std::string& login, const std::string& tableName, const int32_t constraint) = 0;
  virtual void removeIterator(const std::string& login, const std::string& tableName, const std::string& iterName, const std::set<IteratorScope::type> & scopes) = 0;
  virtual void removeTableProperty(const std::string& login, const std::string& tableName, const std::string& property) = 0;
  virtual void renameTable(const std::string& login, const std::string& oldTableName, const std::string& newTableName) = 0;
  virtual void setLocalityGroups(const std::string& login, const std::string& tableName, const std::map<std::string, std::set<std::string> > & groups) = 0;
  virtual void setTableProperty(const std::string& login, const std::string& tableName, const std::string& property, const std::string& value) = 0;
  virtual void splitRangeByTablets(std::set<Range> & _return, const std::string& login, const std::string& tableName, const Range& range, const int32_t maxSplits) = 0;
  virtual bool tableExists(const std::string& login, const std::string& tableName) = 0;
  virtual void tableIdMap(std::map<std::string, std::string> & _return, const std::string& login) = 0;
  virtual bool testTableClassLoad(const std::string& login, const std::string& tableName, const std::string& className, const std::string& asTypeName) = 0;
  virtual void pingTabletServer(const std::string& login, const std::string& tserver) = 0;
  virtual void getActiveScans(std::vector<ActiveScan> & _return, const std::string& login, const std::string& tserver) = 0;
  virtual void getActiveCompactions(std::vector<ActiveCompaction> & _return, const std::string& login, const std::string& tserver) = 0;
  virtual void getSiteConfiguration(std::map<std::string, std::string> & _return, const std::string& login) = 0;
  virtual void getSystemConfiguration(std::map<std::string, std::string> & _return, const std::string& login) = 0;
  virtual void getTabletServers(std::vector<std::string> & _return, const std::string& login) = 0;
  virtual void removeProperty(const std::string& login, const std::string& property) = 0;
  virtual void setProperty(const std::string& login, const std::string& property, const std::string& value) = 0;
  virtual bool testClassLoad(const std::string& login, const std::string& className, const std::string& asTypeName) = 0;
  virtual bool authenticateUser(const std::string& login, const std::string& user, const std::map<std::string, std::string> & properties) = 0;
  virtual void changeUserAuthorizations(const std::string& login, const std::string& user, const std::set<std::string> & authorizations) = 0;
  virtual void changeLocalUserPassword(const std::string& login, const std::string& user, const std::string& password) = 0;
  virtual void createLocalUser(const std::string& login, const std::string& user, const std::string& password) = 0;
  virtual void dropLocalUser(const std::string& login, const std::string& user) = 0;
  virtual void getUserAuthorizations(std::vector<std::string> & _return, const std::string& login, const std::string& user) = 0;
  virtual void grantSystemPermission(const std::string& login, const std::string& user, const SystemPermission::type perm) = 0;
  virtual void grantTablePermission(const std::string& login, const std::string& user, const std::string& table, const TablePermission::type perm) = 0;
  virtual bool hasSystemPermission(const std::string& login, const std::string& user, const SystemPermission::type perm) = 0;
  virtual bool hasTablePermission(const std::string& login, const std::string& user, const std::string& table, const TablePermission::type perm) = 0;
  virtual void listLocalUsers(std::set<std::string> & _return, const std::string& login) = 0;
  virtual void revokeSystemPermission(const std::string& login, const std::string& user, const SystemPermission::type perm) = 0;
  virtual void revokeTablePermission(const std::string& login, const std::string& user, const std::string& table, const TablePermission::type perm) = 0;
  virtual void grantNamespacePermission(const std::string& login, const std::string& user, const std::string& namespaceName, const NamespacePermission::type perm) = 0;
  virtual bool hasNamespacePermission(const std::string& login, const std::string& user, const std::string& namespaceName, const NamespacePermission::type perm) = 0;
  virtual void revokeNamespacePermission(const std::string& login, const std::string& user, const std::string& namespaceName, const NamespacePermission::type perm) = 0;
  virtual void createBatchScanner(std::string& _return, const std::string& login, const std::string& tableName, const BatchScanOptions& options) = 0;
  virtual void createScanner(std::string& _return, const std::string& login, const std::string& tableName, const ScanOptions& options) = 0;
  virtual bool hasNext(const std::string& scanner) = 0;
  virtual void nextEntry(KeyValueAndPeek& _return, const std::string& scanner) = 0;
  virtual void nextK(ScanResult& _return, const std::string& scanner, const int32_t k) = 0;
  virtual void closeScanner(const std::string& scanner) = 0;
  virtual void updateAndFlush(const std::string& login, const std::string& tableName, const std::map<std::string, std::vector<ColumnUpdate> > & cells) = 0;
  virtual void createWriter(std::string& _return, const std::string& login, const std::string& tableName, const WriterOptions& opts) = 0;
  virtual void update(const std::string& writer, const std::map<std::string, std::vector<ColumnUpdate> > & cells) = 0;
  virtual void flush(const std::string& writer) = 0;
  virtual void closeWriter(const std::string& writer) = 0;
  virtual ConditionalStatus::type updateRowConditionally(const std::string& login, const std::string& tableName, const std::string& row, const ConditionalUpdates& updates) = 0;
  virtual void createConditionalWriter(std::string& _return, const std::string& login, const std::string& tableName, const ConditionalWriterOptions& options) = 0;
  virtual void updateRowsConditionally(std::map<std::string, ConditionalStatus::type> & _return, const std::string& conditionalWriter, const std::map<std::string, ConditionalUpdates> & updates) = 0;
  virtual void closeConditionalWriter(const std::string& conditionalWriter) = 0;
  virtual void getRowRange(Range& _return, const std::string& row) = 0;
  virtual void getFollowing(Key& _return, const Key& key, const PartialKey::type part) = 0;
  virtual void systemNamespace(std::string& _return) = 0;
  virtual void defaultNamespace(std::string& _return) = 0;
  virtual void listNamespaces(std::vector<std::string> & _return, const std::string& login) = 0;
  virtual bool namespaceExists(const std::string& login, const std::string& namespaceName) = 0;
  virtual void createNamespace(const std::string& login, const std::string& namespaceName) = 0;
  virtual void deleteNamespace(const std::string& login, const std::string& namespaceName) = 0;
  virtual void renameNamespace(const std::string& login, const std::string& oldNamespaceName, const std::string& newNamespaceName) = 0;
  virtual void setNamespaceProperty(const std::string& login, const std::string& namespaceName, const std::string& property, const std::string& value) = 0;
  virtual void removeNamespaceProperty(const std::string& login, const std::string& namespaceName, const std::string& property) = 0;
  virtual void getNamespaceProperties(std::map<std::string, std::string> & _return, const std::string& login, const std::string& namespaceName) = 0;
  virtual void namespaceIdMap(std::map<std::string, std::string> & _return, const std::string& login) = 0;
  virtual void attachNamespaceIterator(const std::string& login, const std::string& namespaceName, const IteratorSetting& setting, const std::set<IteratorScope::type> & scopes) = 0;
  virtual void removeNamespaceIterator(const std::string& login, const std::string& namespaceName, const std::string& name, const std::set<IteratorScope::type> & scopes) = 0;
  virtual void getNamespaceIteratorSetting(IteratorSetting& _return, const std::string& login, const std::string& namespaceName, const std::string& name, const IteratorScope::type scope) = 0;
  virtual void listNamespaceIterators(std::map<std::string, std::set<IteratorScope::type> > & _return, const std::string& login, const std::string& namespaceName) = 0;
  virtual void checkNamespaceIteratorConflicts(const std::string& login, const std::string& namespaceName, const IteratorSetting& setting, const std::set<IteratorScope::type> & scopes) = 0;
  virtual int32_t addNamespaceConstraint(const std::string& login, const std::string& namespaceName, const std::string& constraintClassName) = 0;
  virtual void removeNamespaceConstraint(const std::string& login, const std::string& namespaceName, const int32_t id) = 0;
  virtual void listNamespaceConstraints(std::map<std::string, int32_t> & _return, const std::string& login, const std::string& namespaceName) = 0;
  virtual bool testNamespaceClassLoad(const std::string& login, const std::string& namespaceName, const std::string& className, const std::string& asTypeName) = 0;
};

class AccumuloProxyIfFactory {
 public:
  typedef AccumuloProxyIf Handler;

  virtual ~AccumuloProxyIfFactory() {}

  virtual AccumuloProxyIf* getHandler(const ::apache::thrift::TConnectionInfo& connInfo) = 0;
  virtual void releaseHandler(AccumuloProxyIf* /* handler */) = 0;
};

class AccumuloProxyIfSingletonFactory : virtual public AccumuloProxyIfFactory {
 public:
  AccumuloProxyIfSingletonFactory(const boost::shared_ptr<AccumuloProxyIf>& iface) : iface_(iface) {}
  virtual ~AccumuloProxyIfSingletonFactory() {}

  virtual AccumuloProxyIf* getHandler(const ::apache::thrift::TConnectionInfo&) {
    return iface_.get();
  }
  virtual void releaseHandler(AccumuloProxyIf* /* handler */) {}

 protected:
  boost::shared_ptr<AccumuloProxyIf> iface_;
};

class AccumuloProxyNull : virtual public AccumuloProxyIf {
 public:
  virtual ~AccumuloProxyNull() {}
  void login(std::string& /* _return */, const std::string& /* principal */, const std::map<std::string, std::string> & /* loginProperties */) {
    return;
  }
  int32_t addConstraint(const std::string& /* login */, const std::string& /* tableName */, const std::string& /* constraintClassName */) {
    int32_t _return = 0;
    return _return;
  }
  void addSplits(const std::string& /* login */, const std::string& /* tableName */, const std::set<std::string> & /* splits */) {
    return;
  }
  void attachIterator(const std::string& /* login */, const std::string& /* tableName */, const IteratorSetting& /* setting */, const std::set<IteratorScope::type> & /* scopes */) {
    return;
  }
  void checkIteratorConflicts(const std::string& /* login */, const std::string& /* tableName */, const IteratorSetting& /* setting */, const std::set<IteratorScope::type> & /* scopes */) {
    return;
  }
  void clearLocatorCache(const std::string& /* login */, const std::string& /* tableName */) {
    return;
  }
  void cloneTable(const std::string& /* login */, const std::string& /* tableName */, const std::string& /* newTableName */, const bool /* flush */, const std::map<std::string, std::string> & /* propertiesToSet */, const std::set<std::string> & /* propertiesToExclude */) {
    return;
  }
  void compactTable(const std::string& /* login */, const std::string& /* tableName */, const std::string& /* startRow */, const std::string& /* endRow */, const std::vector<IteratorSetting> & /* iterators */, const bool /* flush */, const bool /* wait */, const CompactionStrategyConfig& /* compactionStrategy */) {
    return;
  }
  void cancelCompaction(const std::string& /* login */, const std::string& /* tableName */) {
    return;
  }
  void createTable(const std::string& /* login */, const std::string& /* tableName */, const bool /* versioningIter */, const TimeType::type /* type */) {
    return;
  }
  void deleteTable(const std::string& /* login */, const std::string& /* tableName */) {
    return;
  }
  void deleteRows(const std::string& /* login */, const std::string& /* tableName */, const std::string& /* startRow */, const std::string& /* endRow */) {
    return;
  }
  void exportTable(const std::string& /* login */, const std::string& /* tableName */, const std::string& /* exportDir */) {
    return;
  }
  void flushTable(const std::string& /* login */, const std::string& /* tableName */, const std::string& /* startRow */, const std::string& /* endRow */, const bool /* wait */) {
    return;
  }
  void getDiskUsage(std::vector<DiskUsage> & /* _return */, const std::string& /* login */, const std::set<std::string> & /* tables */) {
    return;
  }
  void getLocalityGroups(std::map<std::string, std::set<std::string> > & /* _return */, const std::string& /* login */, const std::string& /* tableName */) {
    return;
  }
  void getIteratorSetting(IteratorSetting& /* _return */, const std::string& /* login */, const std::string& /* tableName */, const std::string& /* iteratorName */, const IteratorScope::type /* scope */) {
    return;
  }
  void getMaxRow(std::string& /* _return */, const std::string& /* login */, const std::string& /* tableName */, const std::set<std::string> & /* auths */, const std::string& /* startRow */, const bool /* startInclusive */, const std::string& /* endRow */, const bool /* endInclusive */) {
    return;
  }
  void getTableProperties(std::map<std::string, std::string> & /* _return */, const std::string& /* login */, const std::string& /* tableName */) {
    return;
  }
  void importDirectory(const std::string& /* login */, const std::string& /* tableName */, const std::string& /* importDir */, const std::string& /* failureDir */, const bool /* setTime */) {
    return;
  }
  void importTable(const std::string& /* login */, const std::string& /* tableName */, const std::string& /* importDir */) {
    return;
  }
  void listSplits(std::vector<std::string> & /* _return */, const std::string& /* login */, const std::string& /* tableName */, const int32_t /* maxSplits */) {
    return;
  }
  void listTables(std::set<std::string> & /* _return */, const std::string& /* login */) {
    return;
  }
  void listIterators(std::map<std::string, std::set<IteratorScope::type> > & /* _return */, const std::string& /* login */, const std::string& /* tableName */) {
    return;
  }
  void listConstraints(std::map<std::string, int32_t> & /* _return */, const std::string& /* login */, const std::string& /* tableName */) {
    return;
  }
  void mergeTablets(const std::string& /* login */, const std::string& /* tableName */, const std::string& /* startRow */, const std::string& /* endRow */) {
    return;
  }
  void offlineTable(const std::string& /* login */, const std::string& /* tableName */, const bool /* wait */) {
    return;
  }
  void onlineTable(const std::string& /* login */, const std::string& /* tableName */, const bool /* wait */) {
    return;
  }
  void removeConstraint(const std::string& /* login */, const std::string& /* tableName */, const int32_t /* constraint */) {
    return;
  }
  void removeIterator(const std::string& /* login */, const std::string& /* tableName */, const std::string& /* iterName */, const std::set<IteratorScope::type> & /* scopes */) {
    return;
  }
  void removeTableProperty(const std::string& /* login */, const std::string& /* tableName */, const std::string& /* property */) {
    return;
  }
  void renameTable(const std::string& /* login */, const std::string& /* oldTableName */, const std::string& /* newTableName */) {
    return;
  }
  void setLocalityGroups(const std::string& /* login */, const std::string& /* tableName */, const std::map<std::string, std::set<std::string> > & /* groups */) {
    return;
  }
  void setTableProperty(const std::string& /* login */, const std::string& /* tableName */, const std::string& /* property */, const std::string& /* value */) {
    return;
  }
  void splitRangeByTablets(std::set<Range> & /* _return */, const std::string& /* login */, const std::string& /* tableName */, const Range& /* range */, const int32_t /* maxSplits */) {
    return;
  }
  bool tableExists(const std::string& /* login */, const std::string& /* tableName */) {
    bool _return = false;
    return _return;
  }
  void tableIdMap(std::map<std::string, std::string> & /* _return */, const std::string& /* login */) {
    return;
  }
  bool testTableClassLoad(const std::string& /* login */, const std::string& /* tableName */, const std::string& /* className */, const std::string& /* asTypeName */) {
    bool _return = false;
    return _return;
  }
  void pingTabletServer(const std::string& /* login */, const std::string& /* tserver */) {
    return;
  }
  void getActiveScans(std::vector<ActiveScan> & /* _return */, const std::string& /* login */, const std::string& /* tserver */) {
    return;
  }
  void getActiveCompactions(std::vector<ActiveCompaction> & /* _return */, const std::string& /* login */, const std::string& /* tserver */) {
    return;
  }
  void getSiteConfiguration(std::map<std::string, std::string> & /* _return */, const std::string& /* login */) {
    return;
  }
  void getSystemConfiguration(std::map<std::string, std::string> & /* _return */, const std::string& /* login */) {
    return;
  }
  void getTabletServers(std::vector<std::string> & /* _return */, const std::string& /* login */) {
    return;
  }
  void removeProperty(const std::string& /* login */, const std::string& /* property */) {
    return;
  }
  void setProperty(const std::string& /* login */, const std::string& /* property */, const std::string& /* value */) {
    return;
  }
  bool testClassLoad(const std::string& /* login */, const std::string& /* className */, const std::string& /* asTypeName */) {
    bool _return = false;
    return _return;
  }
  bool authenticateUser(const std::string& /* login */, const std::string& /* user */, const std::map<std::string, std::string> & /* properties */) {
    bool _return = false;
    return _return;
  }
  void changeUserAuthorizations(const std::string& /* login */, const std::string& /* user */, const std::set<std::string> & /* authorizations */) {
    return;
  }
  void changeLocalUserPassword(const std::string& /* login */, const std::string& /* user */, const std::string& /* password */) {
    return;
  }
  void createLocalUser(const std::string& /* login */, const std::string& /* user */, const std::string& /* password */) {
    return;
  }
  void dropLocalUser(const std::string& /* login */, const std::string& /* user */) {
    return;
  }
  void getUserAuthorizations(std::vector<std::string> & /* _return */, const std::string& /* login */, const std::string& /* user */) {
    return;
  }
  void grantSystemPermission(const std::string& /* login */, const std::string& /* user */, const SystemPermission::type /* perm */) {
    return;
  }
  void grantTablePermission(const std::string& /* login */, const std::string& /* user */, const std::string& /* table */, const TablePermission::type /* perm */) {
    return;
  }
  bool hasSystemPermission(const std::string& /* login */, const std::string& /* user */, const SystemPermission::type /* perm */) {
    bool _return = false;
    return _return;
  }
  bool hasTablePermission(const std::string& /* login */, const std::string& /* user */, const std::string& /* table */, const TablePermission::type /* perm */) {
    bool _return = false;
    return _return;
  }
  void listLocalUsers(std::set<std::string> & /* _return */, const std::string& /* login */) {
    return;
  }
  void revokeSystemPermission(const std::string& /* login */, const std::string& /* user */, const SystemPermission::type /* perm */) {
    return;
  }
  void revokeTablePermission(const std::string& /* login */, const std::string& /* user */, const std::string& /* table */, const TablePermission::type /* perm */) {
    return;
  }
  void grantNamespacePermission(const std::string& /* login */, const std::string& /* user */, const std::string& /* namespaceName */, const NamespacePermission::type /* perm */) {
    return;
  }
  bool hasNamespacePermission(const std::string& /* login */, const std::string& /* user */, const std::string& /* namespaceName */, const NamespacePermission::type /* perm */) {
    bool _return = false;
    return _return;
  }
  void revokeNamespacePermission(const std::string& /* login */, const std::string& /* user */, const std::string& /* namespaceName */, const NamespacePermission::type /* perm */) {
    return;
  }
  void createBatchScanner(std::string& /* _return */, const std::string& /* login */, const std::string& /* tableName */, const BatchScanOptions& /* options */) {
    return;
  }
  void createScanner(std::string& /* _return */, const std::string& /* login */, const std::string& /* tableName */, const ScanOptions& /* options */) {
    return;
  }
  bool hasNext(const std::string& /* scanner */) {
    bool _return = false;
    return _return;
  }
  void nextEntry(KeyValueAndPeek& /* _return */, const std::string& /* scanner */) {
    return;
  }
  void nextK(ScanResult& /* _return */, const std::string& /* scanner */, const int32_t /* k */) {
    return;
  }
  void closeScanner(const std::string& /* scanner */) {
    return;
  }
  void updateAndFlush(const std::string& /* login */, const std::string& /* tableName */, const std::map<std::string, std::vector<ColumnUpdate> > & /* cells */) {
    return;
  }
  void createWriter(std::string& /* _return */, const std::string& /* login */, const std::string& /* tableName */, const WriterOptions& /* opts */) {
    return;
  }
  void update(const std::string& /* writer */, const std::map<std::string, std::vector<ColumnUpdate> > & /* cells */) {
    return;
  }
  void flush(const std::string& /* writer */) {
    return;
  }
  void closeWriter(const std::string& /* writer */) {
    return;
  }
  ConditionalStatus::type updateRowConditionally(const std::string& /* login */, const std::string& /* tableName */, const std::string& /* row */, const ConditionalUpdates& /* updates */) {
    ConditionalStatus::type _return = (ConditionalStatus::type)0;
    return _return;
  }
  void createConditionalWriter(std::string& /* _return */, const std::string& /* login */, const std::string& /* tableName */, const ConditionalWriterOptions& /* options */) {
    return;
  }
  void updateRowsConditionally(std::map<std::string, ConditionalStatus::type> & /* _return */, const std::string& /* conditionalWriter */, const std::map<std::string, ConditionalUpdates> & /* updates */) {
    return;
  }
  void closeConditionalWriter(const std::string& /* conditionalWriter */) {
    return;
  }
  void getRowRange(Range& /* _return */, const std::string& /* row */) {
    return;
  }
  void getFollowing(Key& /* _return */, const Key& /* key */, const PartialKey::type /* part */) {
    return;
  }
  void systemNamespace(std::string& /* _return */) {
    return;
  }
  void defaultNamespace(std::string& /* _return */) {
    return;
  }
  void listNamespaces(std::vector<std::string> & /* _return */, const std::string& /* login */) {
    return;
  }
  bool namespaceExists(const std::string& /* login */, const std::string& /* namespaceName */) {
    bool _return = false;
    return _return;
  }
  void createNamespace(const std::string& /* login */, const std::string& /* namespaceName */) {
    return;
  }
  void deleteNamespace(const std::string& /* login */, const std::string& /* namespaceName */) {
    return;
  }
  void renameNamespace(const std::string& /* login */, const std::string& /* oldNamespaceName */, const std::string& /* newNamespaceName */) {
    return;
  }
  void setNamespaceProperty(const std::string& /* login */, const std::string& /* namespaceName */, const std::string& /* property */, const std::string& /* value */) {
    return;
  }
  void removeNamespaceProperty(const std::string& /* login */, const std::string& /* namespaceName */, const std::string& /* property */) {
    return;
  }
  void getNamespaceProperties(std::map<std::string, std::string> & /* _return */, const std::string& /* login */, const std::string& /* namespaceName */) {
    return;
  }
  void namespaceIdMap(std::map<std::string, std::string> & /* _return */, const std::string& /* login */) {
    return;
  }
  void attachNamespaceIterator(const std::string& /* login */, const std::string& /* namespaceName */, const IteratorSetting& /* setting */, const std::set<IteratorScope::type> & /* scopes */) {
    return;
  }
  void removeNamespaceIterator(const std::string& /* login */, const std::string& /* namespaceName */, const std::string& /* name */, const std::set<IteratorScope::type> & /* scopes */) {
    return;
  }
  void getNamespaceIteratorSetting(IteratorSetting& /* _return */, const std::string& /* login */, const std::string& /* namespaceName */, const std::string& /* name */, const IteratorScope::type /* scope */) {
    return;
  }
  void listNamespaceIterators(std::map<std::string, std::set<IteratorScope::type> > & /* _return */, const std::string& /* login */, const std::string& /* namespaceName */) {
    return;
  }
  void checkNamespaceIteratorConflicts(const std::string& /* login */, const std::string& /* namespaceName */, const IteratorSetting& /* setting */, const std::set<IteratorScope::type> & /* scopes */) {
    return;
  }
  int32_t addNamespaceConstraint(const std::string& /* login */, const std::string& /* namespaceName */, const std::string& /* constraintClassName */) {
    int32_t _return = 0;
    return _return;
  }
  void removeNamespaceConstraint(const std::string& /* login */, const std::string& /* namespaceName */, const int32_t /* id */) {
    return;
  }
  void listNamespaceConstraints(std::map<std::string, int32_t> & /* _return */, const std::string& /* login */, const std::string& /* namespaceName */) {
    return;
  }
  bool testNamespaceClassLoad(const std::string& /* login */, const std::string& /* namespaceName */, const std::string& /* className */, const std::string& /* asTypeName */) {
    bool _return = false;
    return _return;
  }
};

typedef struct _AccumuloProxy_login_args__isset {
  _AccumuloProxy_login_args__isset() : principal(false), loginProperties(false) {}
  bool principal :1;
  bool loginProperties :1;
} _AccumuloProxy_login_args__isset;

class AccumuloProxy_login_args {
 public:

  AccumuloProxy_login_args(const AccumuloProxy_login_args&);
  AccumuloProxy_login_args& operator=(const AccumuloProxy_login_args&);
  AccumuloProxy_login_args() : principal() {
  }

  virtual ~AccumuloProxy_login_args() throw();
  std::string principal;
  std::map<std::string, std::string>  loginProperties;

  _AccumuloProxy_login_args__isset __isset;

  void __set_principal(const std::string& val);

  void __set_loginProperties(const std::map<std::string, std::string> & val);

  bool operator == (const AccumuloProxy_login_args & rhs) const
  {
    if (!(principal == rhs.principal))
      return false;
    if (!(loginProperties == rhs.loginProperties))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_login_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_login_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_login_pargs {
 public:


  virtual ~AccumuloProxy_login_pargs() throw();
  const std::string* principal;
  const std::map<std::string, std::string> * loginProperties;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_login_result__isset {
  _AccumuloProxy_login_result__isset() : success(false), ouch2(false) {}
  bool success :1;
  bool ouch2 :1;
} _AccumuloProxy_login_result__isset;

class AccumuloProxy_login_result {
 public:

  AccumuloProxy_login_result(const AccumuloProxy_login_result&);
  AccumuloProxy_login_result& operator=(const AccumuloProxy_login_result&);
  AccumuloProxy_login_result() : success() {
  }

  virtual ~AccumuloProxy_login_result() throw();
  std::string success;
  AccumuloSecurityException ouch2;

  _AccumuloProxy_login_result__isset __isset;

  void __set_success(const std::string& val);

  void __set_ouch2(const AccumuloSecurityException& val);

  bool operator == (const AccumuloProxy_login_result & rhs) const
  {
    if (!(success == rhs.success))
      return false;
    if (!(ouch2 == rhs.ouch2))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_login_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_login_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_login_presult__isset {
  _AccumuloProxy_login_presult__isset() : success(false), ouch2(false) {}
  bool success :1;
  bool ouch2 :1;
} _AccumuloProxy_login_presult__isset;

class AccumuloProxy_login_presult {
 public:


  virtual ~AccumuloProxy_login_presult() throw();
  std::string* success;
  AccumuloSecurityException ouch2;

  _AccumuloProxy_login_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_addConstraint_args__isset {
  _AccumuloProxy_addConstraint_args__isset() : login(false), tableName(false), constraintClassName(false) {}
  bool login :1;
  bool tableName :1;
  bool constraintClassName :1;
} _AccumuloProxy_addConstraint_args__isset;

class AccumuloProxy_addConstraint_args {
 public:

  AccumuloProxy_addConstraint_args(const AccumuloProxy_addConstraint_args&);
  AccumuloProxy_addConstraint_args& operator=(const AccumuloProxy_addConstraint_args&);
  AccumuloProxy_addConstraint_args() : login(), tableName(), constraintClassName() {
  }

  virtual ~AccumuloProxy_addConstraint_args() throw();
  std::string login;
  std::string tableName;
  std::string constraintClassName;

  _AccumuloProxy_addConstraint_args__isset __isset;

  void __set_login(const std::string& val);

  void __set_tableName(const std::string& val);

  void __set_constraintClassName(const std::string& val);

  bool operator == (const AccumuloProxy_addConstraint_args & rhs) const
  {
    if (!(login == rhs.login))
      return false;
    if (!(tableName == rhs.tableName))
      return false;
    if (!(constraintClassName == rhs.constraintClassName))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_addConstraint_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_addConstraint_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_addConstraint_pargs {
 public:


  virtual ~AccumuloProxy_addConstraint_pargs() throw();
  const std::string* login;
  const std::string* tableName;
  const std::string* constraintClassName;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_addConstraint_result__isset {
  _AccumuloProxy_addConstraint_result__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
  bool success :1;
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_addConstraint_result__isset;

class AccumuloProxy_addConstraint_result {
 public:

  AccumuloProxy_addConstraint_result(const AccumuloProxy_addConstraint_result&);
  AccumuloProxy_addConstraint_result& operator=(const AccumuloProxy_addConstraint_result&);
  AccumuloProxy_addConstraint_result() : success(0) {
  }

  virtual ~AccumuloProxy_addConstraint_result() throw();
  int32_t success;
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  TableNotFoundException ouch3;

  _AccumuloProxy_addConstraint_result__isset __isset;

  void __set_success(const int32_t val);

  void __set_ouch1(const AccumuloException& val);

  void __set_ouch2(const AccumuloSecurityException& val);

  void __set_ouch3(const TableNotFoundException& val);

  bool operator == (const AccumuloProxy_addConstraint_result & rhs) const
  {
    if (!(success == rhs.success))
      return false;
    if (!(ouch1 == rhs.ouch1))
      return false;
    if (!(ouch2 == rhs.ouch2))
      return false;
    if (!(ouch3 == rhs.ouch3))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_addConstraint_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_addConstraint_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_addConstraint_presult__isset {
  _AccumuloProxy_addConstraint_presult__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
  bool success :1;
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_addConstraint_presult__isset;

class AccumuloProxy_addConstraint_presult {
 public:


  virtual ~AccumuloProxy_addConstraint_presult() throw();
  int32_t* success;
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  TableNotFoundException ouch3;

  _AccumuloProxy_addConstraint_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_addSplits_args__isset {
  _AccumuloProxy_addSplits_args__isset() : login(false), tableName(false), splits(false) {}
  bool login :1;
  bool tableName :1;
  bool splits :1;
} _AccumuloProxy_addSplits_args__isset;

class AccumuloProxy_addSplits_args {
 public:

  AccumuloProxy_addSplits_args(const AccumuloProxy_addSplits_args&);
  AccumuloProxy_addSplits_args& operator=(const AccumuloProxy_addSplits_args&);
  AccumuloProxy_addSplits_args() : login(), tableName() {
  }

  virtual ~AccumuloProxy_addSplits_args() throw();
  std::string login;
  std::string tableName;
  std::set<std::string>  splits;

  _AccumuloProxy_addSplits_args__isset __isset;

  void __set_login(const std::string& val);

  void __set_tableName(const std::string& val);

  void __set_splits(const std::set<std::string> & val);

  bool operator == (const AccumuloProxy_addSplits_args & rhs) const
  {
    if (!(login == rhs.login))
      return false;
    if (!(tableName == rhs.tableName))
      return false;
    if (!(splits == rhs.splits))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_addSplits_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_addSplits_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_addSplits_pargs {
 public:


  virtual ~AccumuloProxy_addSplits_pargs() throw();
  const std::string* login;
  const std::string* tableName;
  const std::set<std::string> * splits;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_addSplits_result__isset {
  _AccumuloProxy_addSplits_result__isset() : ouch1(false), ouch2(false), ouch3(false) {}
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_addSplits_result__isset;

class AccumuloProxy_addSplits_result {
 public:

  AccumuloProxy_addSplits_result(const AccumuloProxy_addSplits_result&);
  AccumuloProxy_addSplits_result& operator=(const AccumuloProxy_addSplits_result&);
  AccumuloProxy_addSplits_result() {
  }

  virtual ~AccumuloProxy_addSplits_result() throw();
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  TableNotFoundException ouch3;

  _AccumuloProxy_addSplits_result__isset __isset;

  void __set_ouch1(const AccumuloException& val);

  void __set_ouch2(const AccumuloSecurityException& val);

  void __set_ouch3(const TableNotFoundException& val);

  bool operator == (const AccumuloProxy_addSplits_result & rhs) const
  {
    if (!(ouch1 == rhs.ouch1))
      return false;
    if (!(ouch2 == rhs.ouch2))
      return false;
    if (!(ouch3 == rhs.ouch3))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_addSplits_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_addSplits_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_addSplits_presult__isset {
  _AccumuloProxy_addSplits_presult__isset() : ouch1(false), ouch2(false), ouch3(false) {}
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_addSplits_presult__isset;

class AccumuloProxy_addSplits_presult {
 public:


  virtual ~AccumuloProxy_addSplits_presult() throw();
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  TableNotFoundException ouch3;

  _AccumuloProxy_addSplits_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_attachIterator_args__isset {
  _AccumuloProxy_attachIterator_args__isset() : login(false), tableName(false), setting(false), scopes(false) {}
  bool login :1;
  bool tableName :1;
  bool setting :1;
  bool scopes :1;
} _AccumuloProxy_attachIterator_args__isset;

class AccumuloProxy_attachIterator_args {
 public:

  AccumuloProxy_attachIterator_args(const AccumuloProxy_attachIterator_args&);
  AccumuloProxy_attachIterator_args& operator=(const AccumuloProxy_attachIterator_args&);
  AccumuloProxy_attachIterator_args() : login(), tableName() {
  }

  virtual ~AccumuloProxy_attachIterator_args() throw();
  std::string login;
  std::string tableName;
  IteratorSetting setting;
  std::set<IteratorScope::type>  scopes;

  _AccumuloProxy_attachIterator_args__isset __isset;

  void __set_login(const std::string& val);

  void __set_tableName(const std::string& val);

  void __set_setting(const IteratorSetting& val);

  void __set_scopes(const std::set<IteratorScope::type> & val);

  bool operator == (const AccumuloProxy_attachIterator_args & rhs) const
  {
    if (!(login == rhs.login))
      return false;
    if (!(tableName == rhs.tableName))
      return false;
    if (!(setting == rhs.setting))
      return false;
    if (!(scopes == rhs.scopes))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_attachIterator_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_attachIterator_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_attachIterator_pargs {
 public:


  virtual ~AccumuloProxy_attachIterator_pargs() throw();
  const std::string* login;
  const std::string* tableName;
  const IteratorSetting* setting;
  const std::set<IteratorScope::type> * scopes;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_attachIterator_result__isset {
  _AccumuloProxy_attachIterator_result__isset() : ouch1(false), ouch2(false), ouch3(false) {}
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_attachIterator_result__isset;

class AccumuloProxy_attachIterator_result {
 public:

  AccumuloProxy_attachIterator_result(const AccumuloProxy_attachIterator_result&);
  AccumuloProxy_attachIterator_result& operator=(const AccumuloProxy_attachIterator_result&);
  AccumuloProxy_attachIterator_result() {
  }

  virtual ~AccumuloProxy_attachIterator_result() throw();
  AccumuloSecurityException ouch1;
  AccumuloException ouch2;
  TableNotFoundException ouch3;

  _AccumuloProxy_attachIterator_result__isset __isset;

  void __set_ouch1(const AccumuloSecurityException& val);

  void __set_ouch2(const AccumuloException& val);

  void __set_ouch3(const TableNotFoundException& val);

  bool operator == (const AccumuloProxy_attachIterator_result & rhs) const
  {
    if (!(ouch1 == rhs.ouch1))
      return false;
    if (!(ouch2 == rhs.ouch2))
      return false;
    if (!(ouch3 == rhs.ouch3))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_attachIterator_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_attachIterator_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_attachIterator_presult__isset {
  _AccumuloProxy_attachIterator_presult__isset() : ouch1(false), ouch2(false), ouch3(false) {}
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_attachIterator_presult__isset;

class AccumuloProxy_attachIterator_presult {
 public:


  virtual ~AccumuloProxy_attachIterator_presult() throw();
  AccumuloSecurityException ouch1;
  AccumuloException ouch2;
  TableNotFoundException ouch3;

  _AccumuloProxy_attachIterator_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_checkIteratorConflicts_args__isset {
  _AccumuloProxy_checkIteratorConflicts_args__isset() : login(false), tableName(false), setting(false), scopes(false) {}
  bool login :1;
  bool tableName :1;
  bool setting :1;
  bool scopes :1;
} _AccumuloProxy_checkIteratorConflicts_args__isset;

class AccumuloProxy_checkIteratorConflicts_args {
 public:

  AccumuloProxy_checkIteratorConflicts_args(const AccumuloProxy_checkIteratorConflicts_args&);
  AccumuloProxy_checkIteratorConflicts_args& operator=(const AccumuloProxy_checkIteratorConflicts_args&);
  AccumuloProxy_checkIteratorConflicts_args() : login(), tableName() {
  }

  virtual ~AccumuloProxy_checkIteratorConflicts_args() throw();
  std::string login;
  std::string tableName;
  IteratorSetting setting;
  std::set<IteratorScope::type>  scopes;

  _AccumuloProxy_checkIteratorConflicts_args__isset __isset;

  void __set_login(const std::string& val);

  void __set_tableName(const std::string& val);

  void __set_setting(const IteratorSetting& val);

  void __set_scopes(const std::set<IteratorScope::type> & val);

  bool operator == (const AccumuloProxy_checkIteratorConflicts_args & rhs) const
  {
    if (!(login == rhs.login))
      return false;
    if (!(tableName == rhs.tableName))
      return false;
    if (!(setting == rhs.setting))
      return false;
    if (!(scopes == rhs.scopes))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_checkIteratorConflicts_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_checkIteratorConflicts_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_checkIteratorConflicts_pargs {
 public:


  virtual ~AccumuloProxy_checkIteratorConflicts_pargs() throw();
  const std::string* login;
  const std::string* tableName;
  const IteratorSetting* setting;
  const std::set<IteratorScope::type> * scopes;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_checkIteratorConflicts_result__isset {
  _AccumuloProxy_checkIteratorConflicts_result__isset() : ouch1(false), ouch2(false), ouch3(false) {}
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_checkIteratorConflicts_result__isset;

class AccumuloProxy_checkIteratorConflicts_result {
 public:

  AccumuloProxy_checkIteratorConflicts_result(const AccumuloProxy_checkIteratorConflicts_result&);
  AccumuloProxy_checkIteratorConflicts_result& operator=(const AccumuloProxy_checkIteratorConflicts_result&);
  AccumuloProxy_checkIteratorConflicts_result() {
  }

  virtual ~AccumuloProxy_checkIteratorConflicts_result() throw();
  AccumuloSecurityException ouch1;
  AccumuloException ouch2;
  TableNotFoundException ouch3;

  _AccumuloProxy_checkIteratorConflicts_result__isset __isset;

  void __set_ouch1(const AccumuloSecurityException& val);

  void __set_ouch2(const AccumuloException& val);

  void __set_ouch3(const TableNotFoundException& val);

  bool operator == (const AccumuloProxy_checkIteratorConflicts_result & rhs) const
  {
    if (!(ouch1 == rhs.ouch1))
      return false;
    if (!(ouch2 == rhs.ouch2))
      return false;
    if (!(ouch3 == rhs.ouch3))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_checkIteratorConflicts_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_checkIteratorConflicts_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_checkIteratorConflicts_presult__isset {
  _AccumuloProxy_checkIteratorConflicts_presult__isset() : ouch1(false), ouch2(false), ouch3(false) {}
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_checkIteratorConflicts_presult__isset;

class AccumuloProxy_checkIteratorConflicts_presult {
 public:


  virtual ~AccumuloProxy_checkIteratorConflicts_presult() throw();
  AccumuloSecurityException ouch1;
  AccumuloException ouch2;
  TableNotFoundException ouch3;

  _AccumuloProxy_checkIteratorConflicts_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_clearLocatorCache_args__isset {
  _AccumuloProxy_clearLocatorCache_args__isset() : login(false), tableName(false) {}
  bool login :1;
  bool tableName :1;
} _AccumuloProxy_clearLocatorCache_args__isset;

class AccumuloProxy_clearLocatorCache_args {
 public:

  AccumuloProxy_clearLocatorCache_args(const AccumuloProxy_clearLocatorCache_args&);
  AccumuloProxy_clearLocatorCache_args& operator=(const AccumuloProxy_clearLocatorCache_args&);
  AccumuloProxy_clearLocatorCache_args() : login(), tableName() {
  }

  virtual ~AccumuloProxy_clearLocatorCache_args() throw();
  std::string login;
  std::string tableName;

  _AccumuloProxy_clearLocatorCache_args__isset __isset;

  void __set_login(const std::string& val);

  void __set_tableName(const std::string& val);

  bool operator == (const AccumuloProxy_clearLocatorCache_args & rhs) const
  {
    if (!(login == rhs.login))
      return false;
    if (!(tableName == rhs.tableName))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_clearLocatorCache_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_clearLocatorCache_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_clearLocatorCache_pargs {
 public:


  virtual ~AccumuloProxy_clearLocatorCache_pargs() throw();
  const std::string* login;
  const std::string* tableName;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_clearLocatorCache_result__isset {
  _AccumuloProxy_clearLocatorCache_result__isset() : ouch1(false) {}
  bool ouch1 :1;
} _AccumuloProxy_clearLocatorCache_result__isset;

class AccumuloProxy_clearLocatorCache_result {
 public:

  AccumuloProxy_clearLocatorCache_result(const AccumuloProxy_clearLocatorCache_result&);
  AccumuloProxy_clearLocatorCache_result& operator=(const AccumuloProxy_clearLocatorCache_result&);
  AccumuloProxy_clearLocatorCache_result() {
  }

  virtual ~AccumuloProxy_clearLocatorCache_result() throw();
  TableNotFoundException ouch1;

  _AccumuloProxy_clearLocatorCache_result__isset __isset;

  void __set_ouch1(const TableNotFoundException& val);

  bool operator == (const AccumuloProxy_clearLocatorCache_result & rhs) const
  {
    if (!(ouch1 == rhs.ouch1))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_clearLocatorCache_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_clearLocatorCache_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_clearLocatorCache_presult__isset {
  _AccumuloProxy_clearLocatorCache_presult__isset() : ouch1(false) {}
  bool ouch1 :1;
} _AccumuloProxy_clearLocatorCache_presult__isset;

class AccumuloProxy_clearLocatorCache_presult {
 public:


  virtual ~AccumuloProxy_clearLocatorCache_presult() throw();
  TableNotFoundException ouch1;

  _AccumuloProxy_clearLocatorCache_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_cloneTable_args__isset {
  _AccumuloProxy_cloneTable_args__isset() : login(false), tableName(false), newTableName(false), flush(false), propertiesToSet(false), propertiesToExclude(false) {}
  bool login :1;
  bool tableName :1;
  bool newTableName :1;
  bool flush :1;
  bool propertiesToSet :1;
  bool propertiesToExclude :1;
} _AccumuloProxy_cloneTable_args__isset;

class AccumuloProxy_cloneTable_args {
 public:

  AccumuloProxy_cloneTable_args(const AccumuloProxy_cloneTable_args&);
  AccumuloProxy_cloneTable_args& operator=(const AccumuloProxy_cloneTable_args&);
  AccumuloProxy_cloneTable_args() : login(), tableName(), newTableName(), flush(0) {
  }

  virtual ~AccumuloProxy_cloneTable_args() throw();
  std::string login;
  std::string tableName;
  std::string newTableName;
  bool flush;
  std::map<std::string, std::string>  propertiesToSet;
  std::set<std::string>  propertiesToExclude;

  _AccumuloProxy_cloneTable_args__isset __isset;

  void __set_login(const std::string& val);

  void __set_tableName(const std::string& val);

  void __set_newTableName(const std::string& val);

  void __set_flush(const bool val);

  void __set_propertiesToSet(const std::map<std::string, std::string> & val);

  void __set_propertiesToExclude(const std::set<std::string> & val);

  bool operator == (const AccumuloProxy_cloneTable_args & rhs) const
  {
    if (!(login == rhs.login))
      return false;
    if (!(tableName == rhs.tableName))
      return false;
    if (!(newTableName == rhs.newTableName))
      return false;
    if (!(flush == rhs.flush))
      return false;
    if (!(propertiesToSet == rhs.propertiesToSet))
      return false;
    if (!(propertiesToExclude == rhs.propertiesToExclude))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_cloneTable_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_cloneTable_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_cloneTable_pargs {
 public:


  virtual ~AccumuloProxy_cloneTable_pargs() throw();
  const std::string* login;
  const std::string* tableName;
  const std::string* newTableName;
  const bool* flush;
  const std::map<std::string, std::string> * propertiesToSet;
  const std::set<std::string> * propertiesToExclude;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_cloneTable_result__isset {
  _AccumuloProxy_cloneTable_result__isset() : ouch1(false), ouch2(false), ouch3(false), ouch4(false) {}
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
  bool ouch4 :1;
} _AccumuloProxy_cloneTable_result__isset;

class AccumuloProxy_cloneTable_result {
 public:

  AccumuloProxy_cloneTable_result(const AccumuloProxy_cloneTable_result&);
  AccumuloProxy_cloneTable_result& operator=(const AccumuloProxy_cloneTable_result&);
  AccumuloProxy_cloneTable_result() {
  }

  virtual ~AccumuloProxy_cloneTable_result() throw();
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  TableNotFoundException ouch3;
  TableExistsException ouch4;

  _AccumuloProxy_cloneTable_result__isset __isset;

  void __set_ouch1(const AccumuloException& val);

  void __set_ouch2(const AccumuloSecurityException& val);

  void __set_ouch3(const TableNotFoundException& val);

  void __set_ouch4(const TableExistsException& val);

  bool operator == (const AccumuloProxy_cloneTable_result & rhs) const
  {
    if (!(ouch1 == rhs.ouch1))
      return false;
    if (!(ouch2 == rhs.ouch2))
      return false;
    if (!(ouch3 == rhs.ouch3))
      return false;
    if (!(ouch4 == rhs.ouch4))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_cloneTable_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_cloneTable_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_cloneTable_presult__isset {
  _AccumuloProxy_cloneTable_presult__isset() : ouch1(false), ouch2(false), ouch3(false), ouch4(false) {}
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
  bool ouch4 :1;
} _AccumuloProxy_cloneTable_presult__isset;

class AccumuloProxy_cloneTable_presult {
 public:


  virtual ~AccumuloProxy_cloneTable_presult() throw();
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  TableNotFoundException ouch3;
  TableExistsException ouch4;

  _AccumuloProxy_cloneTable_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_compactTable_args__isset {
  _AccumuloProxy_compactTable_args__isset() : login(false), tableName(false), startRow(false), endRow(false), iterators(false), flush(false), wait(false), compactionStrategy(false) {}
  bool login :1;
  bool tableName :1;
  bool startRow :1;
  bool endRow :1;
  bool iterators :1;
  bool flush :1;
  bool wait :1;
  bool compactionStrategy :1;
} _AccumuloProxy_compactTable_args__isset;

class AccumuloProxy_compactTable_args {
 public:

  AccumuloProxy_compactTable_args(const AccumuloProxy_compactTable_args&);
  AccumuloProxy_compactTable_args& operator=(const AccumuloProxy_compactTable_args&);
  AccumuloProxy_compactTable_args() : login(), tableName(), startRow(), endRow(), flush(0), wait(0) {
  }

  virtual ~AccumuloProxy_compactTable_args() throw();
  std::string login;
  std::string tableName;
  std::string startRow;
  std::string endRow;
  std::vector<IteratorSetting>  iterators;
  bool flush;
  bool wait;
  CompactionStrategyConfig compactionStrategy;

  _AccumuloProxy_compactTable_args__isset __isset;

  void __set_login(const std::string& val);

  void __set_tableName(const std::string& val);

  void __set_startRow(const std::string& val);

  void __set_endRow(const std::string& val);

  void __set_iterators(const std::vector<IteratorSetting> & val);

  void __set_flush(const bool val);

  void __set_wait(const bool val);

  void __set_compactionStrategy(const CompactionStrategyConfig& val);

  bool operator == (const AccumuloProxy_compactTable_args & rhs) const
  {
    if (!(login == rhs.login))
      return false;
    if (!(tableName == rhs.tableName))
      return false;
    if (!(startRow == rhs.startRow))
      return false;
    if (!(endRow == rhs.endRow))
      return false;
    if (!(iterators == rhs.iterators))
      return false;
    if (!(flush == rhs.flush))
      return false;
    if (!(wait == rhs.wait))
      return false;
    if (!(compactionStrategy == rhs.compactionStrategy))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_compactTable_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_compactTable_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_compactTable_pargs {
 public:


  virtual ~AccumuloProxy_compactTable_pargs() throw();
  const std::string* login;
  const std::string* tableName;
  const std::string* startRow;
  const std::string* endRow;
  const std::vector<IteratorSetting> * iterators;
  const bool* flush;
  const bool* wait;
  const CompactionStrategyConfig* compactionStrategy;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_compactTable_result__isset {
  _AccumuloProxy_compactTable_result__isset() : ouch1(false), ouch2(false), ouch3(false) {}
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_compactTable_result__isset;

class AccumuloProxy_compactTable_result {
 public:

  AccumuloProxy_compactTable_result(const AccumuloProxy_compactTable_result&);
  AccumuloProxy_compactTable_result& operator=(const AccumuloProxy_compactTable_result&);
  AccumuloProxy_compactTable_result() {
  }

  virtual ~AccumuloProxy_compactTable_result() throw();
  AccumuloSecurityException ouch1;
  TableNotFoundException ouch2;
  AccumuloException ouch3;

  _AccumuloProxy_compactTable_result__isset __isset;

  void __set_ouch1(const AccumuloSecurityException& val);

  void __set_ouch2(const TableNotFoundException& val);

  void __set_ouch3(const AccumuloException& val);

  bool operator == (const AccumuloProxy_compactTable_result & rhs) const
  {
    if (!(ouch1 == rhs.ouch1))
      return false;
    if (!(ouch2 == rhs.ouch2))
      return false;
    if (!(ouch3 == rhs.ouch3))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_compactTable_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_compactTable_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_compactTable_presult__isset {
  _AccumuloProxy_compactTable_presult__isset() : ouch1(false), ouch2(false), ouch3(false) {}
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_compactTable_presult__isset;

class AccumuloProxy_compactTable_presult {
 public:


  virtual ~AccumuloProxy_compactTable_presult() throw();
  AccumuloSecurityException ouch1;
  TableNotFoundException ouch2;
  AccumuloException ouch3;

  _AccumuloProxy_compactTable_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_cancelCompaction_args__isset {
  _AccumuloProxy_cancelCompaction_args__isset() : login(false), tableName(false) {}
  bool login :1;
  bool tableName :1;
} _AccumuloProxy_cancelCompaction_args__isset;

class AccumuloProxy_cancelCompaction_args {
 public:

  AccumuloProxy_cancelCompaction_args(const AccumuloProxy_cancelCompaction_args&);
  AccumuloProxy_cancelCompaction_args& operator=(const AccumuloProxy_cancelCompaction_args&);
  AccumuloProxy_cancelCompaction_args() : login(), tableName() {
  }

  virtual ~AccumuloProxy_cancelCompaction_args() throw();
  std::string login;
  std::string tableName;

  _AccumuloProxy_cancelCompaction_args__isset __isset;

  void __set_login(const std::string& val);

  void __set_tableName(const std::string& val);

  bool operator == (const AccumuloProxy_cancelCompaction_args & rhs) const
  {
    if (!(login == rhs.login))
      return false;
    if (!(tableName == rhs.tableName))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_cancelCompaction_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_cancelCompaction_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_cancelCompaction_pargs {
 public:


  virtual ~AccumuloProxy_cancelCompaction_pargs() throw();
  const std::string* login;
  const std::string* tableName;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_cancelCompaction_result__isset {
  _AccumuloProxy_cancelCompaction_result__isset() : ouch1(false), ouch2(false), ouch3(false) {}
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_cancelCompaction_result__isset;

class AccumuloProxy_cancelCompaction_result {
 public:

  AccumuloProxy_cancelCompaction_result(const AccumuloProxy_cancelCompaction_result&);
  AccumuloProxy_cancelCompaction_result& operator=(const AccumuloProxy_cancelCompaction_result&);
  AccumuloProxy_cancelCompaction_result() {
  }

  virtual ~AccumuloProxy_cancelCompaction_result() throw();
  AccumuloSecurityException ouch1;
  TableNotFoundException ouch2;
  AccumuloException ouch3;

  _AccumuloProxy_cancelCompaction_result__isset __isset;

  void __set_ouch1(const AccumuloSecurityException& val);

  void __set_ouch2(const TableNotFoundException& val);

  void __set_ouch3(const AccumuloException& val);

  bool operator == (const AccumuloProxy_cancelCompaction_result & rhs) const
  {
    if (!(ouch1 == rhs.ouch1))
      return false;
    if (!(ouch2 == rhs.ouch2))
      return false;
    if (!(ouch3 == rhs.ouch3))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_cancelCompaction_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_cancelCompaction_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_cancelCompaction_presult__isset {
  _AccumuloProxy_cancelCompaction_presult__isset() : ouch1(false), ouch2(false), ouch3(false) {}
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_cancelCompaction_presult__isset;

class AccumuloProxy_cancelCompaction_presult {
 public:


  virtual ~AccumuloProxy_cancelCompaction_presult() throw();
  AccumuloSecurityException ouch1;
  TableNotFoundException ouch2;
  AccumuloException ouch3;

  _AccumuloProxy_cancelCompaction_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_createTable_args__isset {
  _AccumuloProxy_createTable_args__isset() : login(false), tableName(false), versioningIter(false), type(false) {}
  bool login :1;
  bool tableName :1;
  bool versioningIter :1;
  bool type :1;
} _AccumuloProxy_createTable_args__isset;

class AccumuloProxy_createTable_args {
 public:

  AccumuloProxy_createTable_args(const AccumuloProxy_createTable_args&);
  AccumuloProxy_createTable_args& operator=(const AccumuloProxy_createTable_args&);
  AccumuloProxy_createTable_args() : login(), tableName(), versioningIter(0), type((TimeType::type)0) {
  }

  virtual ~AccumuloProxy_createTable_args() throw();
  std::string login;
  std::string tableName;
  bool versioningIter;
  TimeType::type type;

  _AccumuloProxy_createTable_args__isset __isset;

  void __set_login(const std::string& val);

  void __set_tableName(const std::string& val);

  void __set_versioningIter(const bool val);

  void __set_type(const TimeType::type val);

  bool operator == (const AccumuloProxy_createTable_args & rhs) const
  {
    if (!(login == rhs.login))
      return false;
    if (!(tableName == rhs.tableName))
      return false;
    if (!(versioningIter == rhs.versioningIter))
      return false;
    if (!(type == rhs.type))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_createTable_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_createTable_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_createTable_pargs {
 public:


  virtual ~AccumuloProxy_createTable_pargs() throw();
  const std::string* login;
  const std::string* tableName;
  const bool* versioningIter;
  const TimeType::type* type;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_createTable_result__isset {
  _AccumuloProxy_createTable_result__isset() : ouch1(false), ouch2(false), ouch3(false) {}
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_createTable_result__isset;

class AccumuloProxy_createTable_result {
 public:

  AccumuloProxy_createTable_result(const AccumuloProxy_createTable_result&);
  AccumuloProxy_createTable_result& operator=(const AccumuloProxy_createTable_result&);
  AccumuloProxy_createTable_result() {
  }

  virtual ~AccumuloProxy_createTable_result() throw();
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  TableExistsException ouch3;

  _AccumuloProxy_createTable_result__isset __isset;

  void __set_ouch1(const AccumuloException& val);

  void __set_ouch2(const AccumuloSecurityException& val);

  void __set_ouch3(const TableExistsException& val);

  bool operator == (const AccumuloProxy_createTable_result & rhs) const
  {
    if (!(ouch1 == rhs.ouch1))
      return false;
    if (!(ouch2 == rhs.ouch2))
      return false;
    if (!(ouch3 == rhs.ouch3))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_createTable_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_createTable_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_createTable_presult__isset {
  _AccumuloProxy_createTable_presult__isset() : ouch1(false), ouch2(false), ouch3(false) {}
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_createTable_presult__isset;

class AccumuloProxy_createTable_presult {
 public:


  virtual ~AccumuloProxy_createTable_presult() throw();
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  TableExistsException ouch3;

  _AccumuloProxy_createTable_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_deleteTable_args__isset {
  _AccumuloProxy_deleteTable_args__isset() : login(false), tableName(false) {}
  bool login :1;
  bool tableName :1;
} _AccumuloProxy_deleteTable_args__isset;

class AccumuloProxy_deleteTable_args {
 public:

  AccumuloProxy_deleteTable_args(const AccumuloProxy_deleteTable_args&);
  AccumuloProxy_deleteTable_args& operator=(const AccumuloProxy_deleteTable_args&);
  AccumuloProxy_deleteTable_args() : login(), tableName() {
  }

  virtual ~AccumuloProxy_deleteTable_args() throw();
  std::string login;
  std::string tableName;

  _AccumuloProxy_deleteTable_args__isset __isset;

  void __set_login(const std::string& val);

  void __set_tableName(const std::string& val);

  bool operator == (const AccumuloProxy_deleteTable_args & rhs) const
  {
    if (!(login == rhs.login))
      return false;
    if (!(tableName == rhs.tableName))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_deleteTable_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_deleteTable_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_deleteTable_pargs {
 public:


  virtual ~AccumuloProxy_deleteTable_pargs() throw();
  const std::string* login;
  const std::string* tableName;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_deleteTable_result__isset {
  _AccumuloProxy_deleteTable_result__isset() : ouch1(false), ouch2(false), ouch3(false) {}
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_deleteTable_result__isset;

class AccumuloProxy_deleteTable_result {
 public:

  AccumuloProxy_deleteTable_result(const AccumuloProxy_deleteTable_result&);
  AccumuloProxy_deleteTable_result& operator=(const AccumuloProxy_deleteTable_result&);
  AccumuloProxy_deleteTable_result() {
  }

  virtual ~AccumuloProxy_deleteTable_result() throw();
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  TableNotFoundException ouch3;

  _AccumuloProxy_deleteTable_result__isset __isset;

  void __set_ouch1(const AccumuloException& val);

  void __set_ouch2(const AccumuloSecurityException& val);

  void __set_ouch3(const TableNotFoundException& val);

  bool operator == (const AccumuloProxy_deleteTable_result & rhs) const
  {
    if (!(ouch1 == rhs.ouch1))
      return false;
    if (!(ouch2 == rhs.ouch2))
      return false;
    if (!(ouch3 == rhs.ouch3))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_deleteTable_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_deleteTable_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_deleteTable_presult__isset {
  _AccumuloProxy_deleteTable_presult__isset() : ouch1(false), ouch2(false), ouch3(false) {}
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_deleteTable_presult__isset;

class AccumuloProxy_deleteTable_presult {
 public:


  virtual ~AccumuloProxy_deleteTable_presult() throw();
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  TableNotFoundException ouch3;

  _AccumuloProxy_deleteTable_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_deleteRows_args__isset {
  _AccumuloProxy_deleteRows_args__isset() : login(false), tableName(false), startRow(false), endRow(false) {}
  bool login :1;
  bool tableName :1;
  bool startRow :1;
  bool endRow :1;
} _AccumuloProxy_deleteRows_args__isset;

class AccumuloProxy_deleteRows_args {
 public:

  AccumuloProxy_deleteRows_args(const AccumuloProxy_deleteRows_args&);
  AccumuloProxy_deleteRows_args& operator=(const AccumuloProxy_deleteRows_args&);
  AccumuloProxy_deleteRows_args() : login(), tableName(), startRow(), endRow() {
  }

  virtual ~AccumuloProxy_deleteRows_args() throw();
  std::string login;
  std::string tableName;
  std::string startRow;
  std::string endRow;

  _AccumuloProxy_deleteRows_args__isset __isset;

  void __set_login(const std::string& val);

  void __set_tableName(const std::string& val);

  void __set_startRow(const std::string& val);

  void __set_endRow(const std::string& val);

  bool operator == (const AccumuloProxy_deleteRows_args & rhs) const
  {
    if (!(login == rhs.login))
      return false;
    if (!(tableName == rhs.tableName))
      return false;
    if (!(startRow == rhs.startRow))
      return false;
    if (!(endRow == rhs.endRow))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_deleteRows_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_deleteRows_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_deleteRows_pargs {
 public:


  virtual ~AccumuloProxy_deleteRows_pargs() throw();
  const std::string* login;
  const std::string* tableName;
  const std::string* startRow;
  const std::string* endRow;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_deleteRows_result__isset {
  _AccumuloProxy_deleteRows_result__isset() : ouch1(false), ouch2(false), ouch3(false) {}
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_deleteRows_result__isset;

class AccumuloProxy_deleteRows_result {
 public:

  AccumuloProxy_deleteRows_result(const AccumuloProxy_deleteRows_result&);
  AccumuloProxy_deleteRows_result& operator=(const AccumuloProxy_deleteRows_result&);
  AccumuloProxy_deleteRows_result() {
  }

  virtual ~AccumuloProxy_deleteRows_result() throw();
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  TableNotFoundException ouch3;

  _AccumuloProxy_deleteRows_result__isset __isset;

  void __set_ouch1(const AccumuloException& val);

  void __set_ouch2(const AccumuloSecurityException& val);

  void __set_ouch3(const TableNotFoundException& val);

  bool operator == (const AccumuloProxy_deleteRows_result & rhs) const
  {
    if (!(ouch1 == rhs.ouch1))
      return false;
    if (!(ouch2 == rhs.ouch2))
      return false;
    if (!(ouch3 == rhs.ouch3))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_deleteRows_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_deleteRows_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_deleteRows_presult__isset {
  _AccumuloProxy_deleteRows_presult__isset() : ouch1(false), ouch2(false), ouch3(false) {}
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_deleteRows_presult__isset;

class AccumuloProxy_deleteRows_presult {
 public:


  virtual ~AccumuloProxy_deleteRows_presult() throw();
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  TableNotFoundException ouch3;

  _AccumuloProxy_deleteRows_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_exportTable_args__isset {
  _AccumuloProxy_exportTable_args__isset() : login(false), tableName(false), exportDir(false) {}
  bool login :1;
  bool tableName :1;
  bool exportDir :1;
} _AccumuloProxy_exportTable_args__isset;

class AccumuloProxy_exportTable_args {
 public:

  AccumuloProxy_exportTable_args(const AccumuloProxy_exportTable_args&);
  AccumuloProxy_exportTable_args& operator=(const AccumuloProxy_exportTable_args&);
  AccumuloProxy_exportTable_args() : login(), tableName(), exportDir() {
  }

  virtual ~AccumuloProxy_exportTable_args() throw();
  std::string login;
  std::string tableName;
  std::string exportDir;

  _AccumuloProxy_exportTable_args__isset __isset;

  void __set_login(const std::string& val);

  void __set_tableName(const std::string& val);

  void __set_exportDir(const std::string& val);

  bool operator == (const AccumuloProxy_exportTable_args & rhs) const
  {
    if (!(login == rhs.login))
      return false;
    if (!(tableName == rhs.tableName))
      return false;
    if (!(exportDir == rhs.exportDir))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_exportTable_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_exportTable_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_exportTable_pargs {
 public:


  virtual ~AccumuloProxy_exportTable_pargs() throw();
  const std::string* login;
  const std::string* tableName;
  const std::string* exportDir;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_exportTable_result__isset {
  _AccumuloProxy_exportTable_result__isset() : ouch1(false), ouch2(false), ouch3(false) {}
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_exportTable_result__isset;

class AccumuloProxy_exportTable_result {
 public:

  AccumuloProxy_exportTable_result(const AccumuloProxy_exportTable_result&);
  AccumuloProxy_exportTable_result& operator=(const AccumuloProxy_exportTable_result&);
  AccumuloProxy_exportTable_result() {
  }

  virtual ~AccumuloProxy_exportTable_result() throw();
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  TableNotFoundException ouch3;

  _AccumuloProxy_exportTable_result__isset __isset;

  void __set_ouch1(const AccumuloException& val);

  void __set_ouch2(const AccumuloSecurityException& val);

  void __set_ouch3(const TableNotFoundException& val);

  bool operator == (const AccumuloProxy_exportTable_result & rhs) const
  {
    if (!(ouch1 == rhs.ouch1))
      return false;
    if (!(ouch2 == rhs.ouch2))
      return false;
    if (!(ouch3 == rhs.ouch3))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_exportTable_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_exportTable_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_exportTable_presult__isset {
  _AccumuloProxy_exportTable_presult__isset() : ouch1(false), ouch2(false), ouch3(false) {}
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_exportTable_presult__isset;

class AccumuloProxy_exportTable_presult {
 public:


  virtual ~AccumuloProxy_exportTable_presult() throw();
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  TableNotFoundException ouch3;

  _AccumuloProxy_exportTable_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_flushTable_args__isset {
  _AccumuloProxy_flushTable_args__isset() : login(false), tableName(false), startRow(false), endRow(false), wait(false) {}
  bool login :1;
  bool tableName :1;
  bool startRow :1;
  bool endRow :1;
  bool wait :1;
} _AccumuloProxy_flushTable_args__isset;

class AccumuloProxy_flushTable_args {
 public:

  AccumuloProxy_flushTable_args(const AccumuloProxy_flushTable_args&);
  AccumuloProxy_flushTable_args& operator=(const AccumuloProxy_flushTable_args&);
  AccumuloProxy_flushTable_args() : login(), tableName(), startRow(), endRow(), wait(0) {
  }

  virtual ~AccumuloProxy_flushTable_args() throw();
  std::string login;
  std::string tableName;
  std::string startRow;
  std::string endRow;
  bool wait;

  _AccumuloProxy_flushTable_args__isset __isset;

  void __set_login(const std::string& val);

  void __set_tableName(const std::string& val);

  void __set_startRow(const std::string& val);

  void __set_endRow(const std::string& val);

  void __set_wait(const bool val);

  bool operator == (const AccumuloProxy_flushTable_args & rhs) const
  {
    if (!(login == rhs.login))
      return false;
    if (!(tableName == rhs.tableName))
      return false;
    if (!(startRow == rhs.startRow))
      return false;
    if (!(endRow == rhs.endRow))
      return false;
    if (!(wait == rhs.wait))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_flushTable_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_flushTable_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_flushTable_pargs {
 public:


  virtual ~AccumuloProxy_flushTable_pargs() throw();
  const std::string* login;
  const std::string* tableName;
  const std::string* startRow;
  const std::string* endRow;
  const bool* wait;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_flushTable_result__isset {
  _AccumuloProxy_flushTable_result__isset() : ouch1(false), ouch2(false), ouch3(false) {}
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_flushTable_result__isset;

class AccumuloProxy_flushTable_result {
 public:

  AccumuloProxy_flushTable_result(const AccumuloProxy_flushTable_result&);
  AccumuloProxy_flushTable_result& operator=(const AccumuloProxy_flushTable_result&);
  AccumuloProxy_flushTable_result() {
  }

  virtual ~AccumuloProxy_flushTable_result() throw();
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  TableNotFoundException ouch3;

  _AccumuloProxy_flushTable_result__isset __isset;

  void __set_ouch1(const AccumuloException& val);

  void __set_ouch2(const AccumuloSecurityException& val);

  void __set_ouch3(const TableNotFoundException& val);

  bool operator == (const AccumuloProxy_flushTable_result & rhs) const
  {
    if (!(ouch1 == rhs.ouch1))
      return false;
    if (!(ouch2 == rhs.ouch2))
      return false;
    if (!(ouch3 == rhs.ouch3))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_flushTable_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_flushTable_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_flushTable_presult__isset {
  _AccumuloProxy_flushTable_presult__isset() : ouch1(false), ouch2(false), ouch3(false) {}
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_flushTable_presult__isset;

class AccumuloProxy_flushTable_presult {
 public:


  virtual ~AccumuloProxy_flushTable_presult() throw();
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  TableNotFoundException ouch3;

  _AccumuloProxy_flushTable_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_getDiskUsage_args__isset {
  _AccumuloProxy_getDiskUsage_args__isset() : login(false), tables(false) {}
  bool login :1;
  bool tables :1;
} _AccumuloProxy_getDiskUsage_args__isset;

class AccumuloProxy_getDiskUsage_args {
 public:

  AccumuloProxy_getDiskUsage_args(const AccumuloProxy_getDiskUsage_args&);
  AccumuloProxy_getDiskUsage_args& operator=(const AccumuloProxy_getDiskUsage_args&);
  AccumuloProxy_getDiskUsage_args() : login() {
  }

  virtual ~AccumuloProxy_getDiskUsage_args() throw();
  std::string login;
  std::set<std::string>  tables;

  _AccumuloProxy_getDiskUsage_args__isset __isset;

  void __set_login(const std::string& val);

  void __set_tables(const std::set<std::string> & val);

  bool operator == (const AccumuloProxy_getDiskUsage_args & rhs) const
  {
    if (!(login == rhs.login))
      return false;
    if (!(tables == rhs.tables))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_getDiskUsage_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_getDiskUsage_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_getDiskUsage_pargs {
 public:


  virtual ~AccumuloProxy_getDiskUsage_pargs() throw();
  const std::string* login;
  const std::set<std::string> * tables;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_getDiskUsage_result__isset {
  _AccumuloProxy_getDiskUsage_result__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
  bool success :1;
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_getDiskUsage_result__isset;

class AccumuloProxy_getDiskUsage_result {
 public:

  AccumuloProxy_getDiskUsage_result(const AccumuloProxy_getDiskUsage_result&);
  AccumuloProxy_getDiskUsage_result& operator=(const AccumuloProxy_getDiskUsage_result&);
  AccumuloProxy_getDiskUsage_result() {
  }

  virtual ~AccumuloProxy_getDiskUsage_result() throw();
  std::vector<DiskUsage>  success;
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  TableNotFoundException ouch3;

  _AccumuloProxy_getDiskUsage_result__isset __isset;

  void __set_success(const std::vector<DiskUsage> & val);

  void __set_ouch1(const AccumuloException& val);

  void __set_ouch2(const AccumuloSecurityException& val);

  void __set_ouch3(const TableNotFoundException& val);

  bool operator == (const AccumuloProxy_getDiskUsage_result & rhs) const
  {
    if (!(success == rhs.success))
      return false;
    if (!(ouch1 == rhs.ouch1))
      return false;
    if (!(ouch2 == rhs.ouch2))
      return false;
    if (!(ouch3 == rhs.ouch3))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_getDiskUsage_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_getDiskUsage_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_getDiskUsage_presult__isset {
  _AccumuloProxy_getDiskUsage_presult__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
  bool success :1;
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_getDiskUsage_presult__isset;

class AccumuloProxy_getDiskUsage_presult {
 public:


  virtual ~AccumuloProxy_getDiskUsage_presult() throw();
  std::vector<DiskUsage> * success;
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  TableNotFoundException ouch3;

  _AccumuloProxy_getDiskUsage_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_getLocalityGroups_args__isset {
  _AccumuloProxy_getLocalityGroups_args__isset() : login(false), tableName(false) {}
  bool login :1;
  bool tableName :1;
} _AccumuloProxy_getLocalityGroups_args__isset;

class AccumuloProxy_getLocalityGroups_args {
 public:

  AccumuloProxy_getLocalityGroups_args(const AccumuloProxy_getLocalityGroups_args&);
  AccumuloProxy_getLocalityGroups_args& operator=(const AccumuloProxy_getLocalityGroups_args&);
  AccumuloProxy_getLocalityGroups_args() : login(), tableName() {
  }

  virtual ~AccumuloProxy_getLocalityGroups_args() throw();
  std::string login;
  std::string tableName;

  _AccumuloProxy_getLocalityGroups_args__isset __isset;

  void __set_login(const std::string& val);

  void __set_tableName(const std::string& val);

  bool operator == (const AccumuloProxy_getLocalityGroups_args & rhs) const
  {
    if (!(login == rhs.login))
      return false;
    if (!(tableName == rhs.tableName))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_getLocalityGroups_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_getLocalityGroups_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_getLocalityGroups_pargs {
 public:


  virtual ~AccumuloProxy_getLocalityGroups_pargs() throw();
  const std::string* login;
  const std::string* tableName;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_getLocalityGroups_result__isset {
  _AccumuloProxy_getLocalityGroups_result__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
  bool success :1;
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_getLocalityGroups_result__isset;

class AccumuloProxy_getLocalityGroups_result {
 public:

  AccumuloProxy_getLocalityGroups_result(const AccumuloProxy_getLocalityGroups_result&);
  AccumuloProxy_getLocalityGroups_result& operator=(const AccumuloProxy_getLocalityGroups_result&);
  AccumuloProxy_getLocalityGroups_result() {
  }

  virtual ~AccumuloProxy_getLocalityGroups_result() throw();
  std::map<std::string, std::set<std::string> >  success;
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  TableNotFoundException ouch3;

  _AccumuloProxy_getLocalityGroups_result__isset __isset;

  void __set_success(const std::map<std::string, std::set<std::string> > & val);

  void __set_ouch1(const AccumuloException& val);

  void __set_ouch2(const AccumuloSecurityException& val);

  void __set_ouch3(const TableNotFoundException& val);

  bool operator == (const AccumuloProxy_getLocalityGroups_result & rhs) const
  {
    if (!(success == rhs.success))
      return false;
    if (!(ouch1 == rhs.ouch1))
      return false;
    if (!(ouch2 == rhs.ouch2))
      return false;
    if (!(ouch3 == rhs.ouch3))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_getLocalityGroups_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_getLocalityGroups_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_getLocalityGroups_presult__isset {
  _AccumuloProxy_getLocalityGroups_presult__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
  bool success :1;
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_getLocalityGroups_presult__isset;

class AccumuloProxy_getLocalityGroups_presult {
 public:


  virtual ~AccumuloProxy_getLocalityGroups_presult() throw();
  std::map<std::string, std::set<std::string> > * success;
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  TableNotFoundException ouch3;

  _AccumuloProxy_getLocalityGroups_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_getIteratorSetting_args__isset {
  _AccumuloProxy_getIteratorSetting_args__isset() : login(false), tableName(false), iteratorName(false), scope(false) {}
  bool login :1;
  bool tableName :1;
  bool iteratorName :1;
  bool scope :1;
} _AccumuloProxy_getIteratorSetting_args__isset;

class AccumuloProxy_getIteratorSetting_args {
 public:

  AccumuloProxy_getIteratorSetting_args(const AccumuloProxy_getIteratorSetting_args&);
  AccumuloProxy_getIteratorSetting_args& operator=(const AccumuloProxy_getIteratorSetting_args&);
  AccumuloProxy_getIteratorSetting_args() : login(), tableName(), iteratorName(), scope((IteratorScope::type)0) {
  }

  virtual ~AccumuloProxy_getIteratorSetting_args() throw();
  std::string login;
  std::string tableName;
  std::string iteratorName;
  IteratorScope::type scope;

  _AccumuloProxy_getIteratorSetting_args__isset __isset;

  void __set_login(const std::string& val);

  void __set_tableName(const std::string& val);

  void __set_iteratorName(const std::string& val);

  void __set_scope(const IteratorScope::type val);

  bool operator == (const AccumuloProxy_getIteratorSetting_args & rhs) const
  {
    if (!(login == rhs.login))
      return false;
    if (!(tableName == rhs.tableName))
      return false;
    if (!(iteratorName == rhs.iteratorName))
      return false;
    if (!(scope == rhs.scope))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_getIteratorSetting_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_getIteratorSetting_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_getIteratorSetting_pargs {
 public:


  virtual ~AccumuloProxy_getIteratorSetting_pargs() throw();
  const std::string* login;
  const std::string* tableName;
  const std::string* iteratorName;
  const IteratorScope::type* scope;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_getIteratorSetting_result__isset {
  _AccumuloProxy_getIteratorSetting_result__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
  bool success :1;
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_getIteratorSetting_result__isset;

class AccumuloProxy_getIteratorSetting_result {
 public:

  AccumuloProxy_getIteratorSetting_result(const AccumuloProxy_getIteratorSetting_result&);
  AccumuloProxy_getIteratorSetting_result& operator=(const AccumuloProxy_getIteratorSetting_result&);
  AccumuloProxy_getIteratorSetting_result() {
  }

  virtual ~AccumuloProxy_getIteratorSetting_result() throw();
  IteratorSetting success;
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  TableNotFoundException ouch3;

  _AccumuloProxy_getIteratorSetting_result__isset __isset;

  void __set_success(const IteratorSetting& val);

  void __set_ouch1(const AccumuloException& val);

  void __set_ouch2(const AccumuloSecurityException& val);

  void __set_ouch3(const TableNotFoundException& val);

  bool operator == (const AccumuloProxy_getIteratorSetting_result & rhs) const
  {
    if (!(success == rhs.success))
      return false;
    if (!(ouch1 == rhs.ouch1))
      return false;
    if (!(ouch2 == rhs.ouch2))
      return false;
    if (!(ouch3 == rhs.ouch3))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_getIteratorSetting_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_getIteratorSetting_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_getIteratorSetting_presult__isset {
  _AccumuloProxy_getIteratorSetting_presult__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
  bool success :1;
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_getIteratorSetting_presult__isset;

class AccumuloProxy_getIteratorSetting_presult {
 public:


  virtual ~AccumuloProxy_getIteratorSetting_presult() throw();
  IteratorSetting* success;
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  TableNotFoundException ouch3;

  _AccumuloProxy_getIteratorSetting_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_getMaxRow_args__isset {
  _AccumuloProxy_getMaxRow_args__isset() : login(false), tableName(false), auths(false), startRow(false), startInclusive(false), endRow(false), endInclusive(false) {}
  bool login :1;
  bool tableName :1;
  bool auths :1;
  bool startRow :1;
  bool startInclusive :1;
  bool endRow :1;
  bool endInclusive :1;
} _AccumuloProxy_getMaxRow_args__isset;

class AccumuloProxy_getMaxRow_args {
 public:

  AccumuloProxy_getMaxRow_args(const AccumuloProxy_getMaxRow_args&);
  AccumuloProxy_getMaxRow_args& operator=(const AccumuloProxy_getMaxRow_args&);
  AccumuloProxy_getMaxRow_args() : login(), tableName(), startRow(), startInclusive(0), endRow(), endInclusive(0) {
  }

  virtual ~AccumuloProxy_getMaxRow_args() throw();
  std::string login;
  std::string tableName;
  std::set<std::string>  auths;
  std::string startRow;
  bool startInclusive;
  std::string endRow;
  bool endInclusive;

  _AccumuloProxy_getMaxRow_args__isset __isset;

  void __set_login(const std::string& val);

  void __set_tableName(const std::string& val);

  void __set_auths(const std::set<std::string> & val);

  void __set_startRow(const std::string& val);

  void __set_startInclusive(const bool val);

  void __set_endRow(const std::string& val);

  void __set_endInclusive(const bool val);

  bool operator == (const AccumuloProxy_getMaxRow_args & rhs) const
  {
    if (!(login == rhs.login))
      return false;
    if (!(tableName == rhs.tableName))
      return false;
    if (!(auths == rhs.auths))
      return false;
    if (!(startRow == rhs.startRow))
      return false;
    if (!(startInclusive == rhs.startInclusive))
      return false;
    if (!(endRow == rhs.endRow))
      return false;
    if (!(endInclusive == rhs.endInclusive))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_getMaxRow_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_getMaxRow_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_getMaxRow_pargs {
 public:


  virtual ~AccumuloProxy_getMaxRow_pargs() throw();
  const std::string* login;
  const std::string* tableName;
  const std::set<std::string> * auths;
  const std::string* startRow;
  const bool* startInclusive;
  const std::string* endRow;
  const bool* endInclusive;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_getMaxRow_result__isset {
  _AccumuloProxy_getMaxRow_result__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
  bool success :1;
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_getMaxRow_result__isset;

class AccumuloProxy_getMaxRow_result {
 public:

  AccumuloProxy_getMaxRow_result(const AccumuloProxy_getMaxRow_result&);
  AccumuloProxy_getMaxRow_result& operator=(const AccumuloProxy_getMaxRow_result&);
  AccumuloProxy_getMaxRow_result() : success() {
  }

  virtual ~AccumuloProxy_getMaxRow_result() throw();
  std::string success;
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  TableNotFoundException ouch3;

  _AccumuloProxy_getMaxRow_result__isset __isset;

  void __set_success(const std::string& val);

  void __set_ouch1(const AccumuloException& val);

  void __set_ouch2(const AccumuloSecurityException& val);

  void __set_ouch3(const TableNotFoundException& val);

  bool operator == (const AccumuloProxy_getMaxRow_result & rhs) const
  {
    if (!(success == rhs.success))
      return false;
    if (!(ouch1 == rhs.ouch1))
      return false;
    if (!(ouch2 == rhs.ouch2))
      return false;
    if (!(ouch3 == rhs.ouch3))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_getMaxRow_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_getMaxRow_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_getMaxRow_presult__isset {
  _AccumuloProxy_getMaxRow_presult__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
  bool success :1;
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_getMaxRow_presult__isset;

class AccumuloProxy_getMaxRow_presult {
 public:


  virtual ~AccumuloProxy_getMaxRow_presult() throw();
  std::string* success;
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  TableNotFoundException ouch3;

  _AccumuloProxy_getMaxRow_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_getTableProperties_args__isset {
  _AccumuloProxy_getTableProperties_args__isset() : login(false), tableName(false) {}
  bool login :1;
  bool tableName :1;
} _AccumuloProxy_getTableProperties_args__isset;

class AccumuloProxy_getTableProperties_args {
 public:

  AccumuloProxy_getTableProperties_args(const AccumuloProxy_getTableProperties_args&);
  AccumuloProxy_getTableProperties_args& operator=(const AccumuloProxy_getTableProperties_args&);
  AccumuloProxy_getTableProperties_args() : login(), tableName() {
  }

  virtual ~AccumuloProxy_getTableProperties_args() throw();
  std::string login;
  std::string tableName;

  _AccumuloProxy_getTableProperties_args__isset __isset;

  void __set_login(const std::string& val);

  void __set_tableName(const std::string& val);

  bool operator == (const AccumuloProxy_getTableProperties_args & rhs) const
  {
    if (!(login == rhs.login))
      return false;
    if (!(tableName == rhs.tableName))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_getTableProperties_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_getTableProperties_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_getTableProperties_pargs {
 public:


  virtual ~AccumuloProxy_getTableProperties_pargs() throw();
  const std::string* login;
  const std::string* tableName;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_getTableProperties_result__isset {
  _AccumuloProxy_getTableProperties_result__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
  bool success :1;
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_getTableProperties_result__isset;

class AccumuloProxy_getTableProperties_result {
 public:

  AccumuloProxy_getTableProperties_result(const AccumuloProxy_getTableProperties_result&);
  AccumuloProxy_getTableProperties_result& operator=(const AccumuloProxy_getTableProperties_result&);
  AccumuloProxy_getTableProperties_result() {
  }

  virtual ~AccumuloProxy_getTableProperties_result() throw();
  std::map<std::string, std::string>  success;
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  TableNotFoundException ouch3;

  _AccumuloProxy_getTableProperties_result__isset __isset;

  void __set_success(const std::map<std::string, std::string> & val);

  void __set_ouch1(const AccumuloException& val);

  void __set_ouch2(const AccumuloSecurityException& val);

  void __set_ouch3(const TableNotFoundException& val);

  bool operator == (const AccumuloProxy_getTableProperties_result & rhs) const
  {
    if (!(success == rhs.success))
      return false;
    if (!(ouch1 == rhs.ouch1))
      return false;
    if (!(ouch2 == rhs.ouch2))
      return false;
    if (!(ouch3 == rhs.ouch3))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_getTableProperties_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_getTableProperties_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_getTableProperties_presult__isset {
  _AccumuloProxy_getTableProperties_presult__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
  bool success :1;
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_getTableProperties_presult__isset;

class AccumuloProxy_getTableProperties_presult {
 public:


  virtual ~AccumuloProxy_getTableProperties_presult() throw();
  std::map<std::string, std::string> * success;
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  TableNotFoundException ouch3;

  _AccumuloProxy_getTableProperties_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_importDirectory_args__isset {
  _AccumuloProxy_importDirectory_args__isset() : login(false), tableName(false), importDir(false), failureDir(false), setTime(false) {}
  bool login :1;
  bool tableName :1;
  bool importDir :1;
  bool failureDir :1;
  bool setTime :1;
} _AccumuloProxy_importDirectory_args__isset;

class AccumuloProxy_importDirectory_args {
 public:

  AccumuloProxy_importDirectory_args(const AccumuloProxy_importDirectory_args&);
  AccumuloProxy_importDirectory_args& operator=(const AccumuloProxy_importDirectory_args&);
  AccumuloProxy_importDirectory_args() : login(), tableName(), importDir(), failureDir(), setTime(0) {
  }

  virtual ~AccumuloProxy_importDirectory_args() throw();
  std::string login;
  std::string tableName;
  std::string importDir;
  std::string failureDir;
  bool setTime;

  _AccumuloProxy_importDirectory_args__isset __isset;

  void __set_login(const std::string& val);

  void __set_tableName(const std::string& val);

  void __set_importDir(const std::string& val);

  void __set_failureDir(const std::string& val);

  void __set_setTime(const bool val);

  bool operator == (const AccumuloProxy_importDirectory_args & rhs) const
  {
    if (!(login == rhs.login))
      return false;
    if (!(tableName == rhs.tableName))
      return false;
    if (!(importDir == rhs.importDir))
      return false;
    if (!(failureDir == rhs.failureDir))
      return false;
    if (!(setTime == rhs.setTime))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_importDirectory_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_importDirectory_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_importDirectory_pargs {
 public:


  virtual ~AccumuloProxy_importDirectory_pargs() throw();
  const std::string* login;
  const std::string* tableName;
  const std::string* importDir;
  const std::string* failureDir;
  const bool* setTime;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_importDirectory_result__isset {
  _AccumuloProxy_importDirectory_result__isset() : ouch1(false), ouch3(false), ouch4(false) {}
  bool ouch1 :1;
  bool ouch3 :1;
  bool ouch4 :1;
} _AccumuloProxy_importDirectory_result__isset;

class AccumuloProxy_importDirectory_result {
 public:

  AccumuloProxy_importDirectory_result(const AccumuloProxy_importDirectory_result&);
  AccumuloProxy_importDirectory_result& operator=(const AccumuloProxy_importDirectory_result&);
  AccumuloProxy_importDirectory_result() {
  }

  virtual ~AccumuloProxy_importDirectory_result() throw();
  TableNotFoundException ouch1;
  AccumuloException ouch3;
  AccumuloSecurityException ouch4;

  _AccumuloProxy_importDirectory_result__isset __isset;

  void __set_ouch1(const TableNotFoundException& val);

  void __set_ouch3(const AccumuloException& val);

  void __set_ouch4(const AccumuloSecurityException& val);

  bool operator == (const AccumuloProxy_importDirectory_result & rhs) const
  {
    if (!(ouch1 == rhs.ouch1))
      return false;
    if (!(ouch3 == rhs.ouch3))
      return false;
    if (!(ouch4 == rhs.ouch4))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_importDirectory_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_importDirectory_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_importDirectory_presult__isset {
  _AccumuloProxy_importDirectory_presult__isset() : ouch1(false), ouch3(false), ouch4(false) {}
  bool ouch1 :1;
  bool ouch3 :1;
  bool ouch4 :1;
} _AccumuloProxy_importDirectory_presult__isset;

class AccumuloProxy_importDirectory_presult {
 public:


  virtual ~AccumuloProxy_importDirectory_presult() throw();
  TableNotFoundException ouch1;
  AccumuloException ouch3;
  AccumuloSecurityException ouch4;

  _AccumuloProxy_importDirectory_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_importTable_args__isset {
  _AccumuloProxy_importTable_args__isset() : login(false), tableName(false), importDir(false) {}
  bool login :1;
  bool tableName :1;
  bool importDir :1;
} _AccumuloProxy_importTable_args__isset;

class AccumuloProxy_importTable_args {
 public:

  AccumuloProxy_importTable_args(const AccumuloProxy_importTable_args&);
  AccumuloProxy_importTable_args& operator=(const AccumuloProxy_importTable_args&);
  AccumuloProxy_importTable_args() : login(), tableName(), importDir() {
  }

  virtual ~AccumuloProxy_importTable_args() throw();
  std::string login;
  std::string tableName;
  std::string importDir;

  _AccumuloProxy_importTable_args__isset __isset;

  void __set_login(const std::string& val);

  void __set_tableName(const std::string& val);

  void __set_importDir(const std::string& val);

  bool operator == (const AccumuloProxy_importTable_args & rhs) const
  {
    if (!(login == rhs.login))
      return false;
    if (!(tableName == rhs.tableName))
      return false;
    if (!(importDir == rhs.importDir))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_importTable_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_importTable_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_importTable_pargs {
 public:


  virtual ~AccumuloProxy_importTable_pargs() throw();
  const std::string* login;
  const std::string* tableName;
  const std::string* importDir;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_importTable_result__isset {
  _AccumuloProxy_importTable_result__isset() : ouch1(false), ouch2(false), ouch3(false) {}
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_importTable_result__isset;

class AccumuloProxy_importTable_result {
 public:

  AccumuloProxy_importTable_result(const AccumuloProxy_importTable_result&);
  AccumuloProxy_importTable_result& operator=(const AccumuloProxy_importTable_result&);
  AccumuloProxy_importTable_result() {
  }

  virtual ~AccumuloProxy_importTable_result() throw();
  TableExistsException ouch1;
  AccumuloException ouch2;
  AccumuloSecurityException ouch3;

  _AccumuloProxy_importTable_result__isset __isset;

  void __set_ouch1(const TableExistsException& val);

  void __set_ouch2(const AccumuloException& val);

  void __set_ouch3(const AccumuloSecurityException& val);

  bool operator == (const AccumuloProxy_importTable_result & rhs) const
  {
    if (!(ouch1 == rhs.ouch1))
      return false;
    if (!(ouch2 == rhs.ouch2))
      return false;
    if (!(ouch3 == rhs.ouch3))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_importTable_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_importTable_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_importTable_presult__isset {
  _AccumuloProxy_importTable_presult__isset() : ouch1(false), ouch2(false), ouch3(false) {}
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_importTable_presult__isset;

class AccumuloProxy_importTable_presult {
 public:


  virtual ~AccumuloProxy_importTable_presult() throw();
  TableExistsException ouch1;
  AccumuloException ouch2;
  AccumuloSecurityException ouch3;

  _AccumuloProxy_importTable_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_listSplits_args__isset {
  _AccumuloProxy_listSplits_args__isset() : login(false), tableName(false), maxSplits(false) {}
  bool login :1;
  bool tableName :1;
  bool maxSplits :1;
} _AccumuloProxy_listSplits_args__isset;

class AccumuloProxy_listSplits_args {
 public:

  AccumuloProxy_listSplits_args(const AccumuloProxy_listSplits_args&);
  AccumuloProxy_listSplits_args& operator=(const AccumuloProxy_listSplits_args&);
  AccumuloProxy_listSplits_args() : login(), tableName(), maxSplits(0) {
  }

  virtual ~AccumuloProxy_listSplits_args() throw();
  std::string login;
  std::string tableName;
  int32_t maxSplits;

  _AccumuloProxy_listSplits_args__isset __isset;

  void __set_login(const std::string& val);

  void __set_tableName(const std::string& val);

  void __set_maxSplits(const int32_t val);

  bool operator == (const AccumuloProxy_listSplits_args & rhs) const
  {
    if (!(login == rhs.login))
      return false;
    if (!(tableName == rhs.tableName))
      return false;
    if (!(maxSplits == rhs.maxSplits))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_listSplits_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_listSplits_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_listSplits_pargs {
 public:


  virtual ~AccumuloProxy_listSplits_pargs() throw();
  const std::string* login;
  const std::string* tableName;
  const int32_t* maxSplits;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_listSplits_result__isset {
  _AccumuloProxy_listSplits_result__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
  bool success :1;
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_listSplits_result__isset;

class AccumuloProxy_listSplits_result {
 public:

  AccumuloProxy_listSplits_result(const AccumuloProxy_listSplits_result&);
  AccumuloProxy_listSplits_result& operator=(const AccumuloProxy_listSplits_result&);
  AccumuloProxy_listSplits_result() {
  }

  virtual ~AccumuloProxy_listSplits_result() throw();
  std::vector<std::string>  success;
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  TableNotFoundException ouch3;

  _AccumuloProxy_listSplits_result__isset __isset;

  void __set_success(const std::vector<std::string> & val);

  void __set_ouch1(const AccumuloException& val);

  void __set_ouch2(const AccumuloSecurityException& val);

  void __set_ouch3(const TableNotFoundException& val);

  bool operator == (const AccumuloProxy_listSplits_result & rhs) const
  {
    if (!(success == rhs.success))
      return false;
    if (!(ouch1 == rhs.ouch1))
      return false;
    if (!(ouch2 == rhs.ouch2))
      return false;
    if (!(ouch3 == rhs.ouch3))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_listSplits_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_listSplits_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_listSplits_presult__isset {
  _AccumuloProxy_listSplits_presult__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
  bool success :1;
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_listSplits_presult__isset;

class AccumuloProxy_listSplits_presult {
 public:


  virtual ~AccumuloProxy_listSplits_presult() throw();
  std::vector<std::string> * success;
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  TableNotFoundException ouch3;

  _AccumuloProxy_listSplits_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_listTables_args__isset {
  _AccumuloProxy_listTables_args__isset() : login(false) {}
  bool login :1;
} _AccumuloProxy_listTables_args__isset;

class AccumuloProxy_listTables_args {
 public:

  AccumuloProxy_listTables_args(const AccumuloProxy_listTables_args&);
  AccumuloProxy_listTables_args& operator=(const AccumuloProxy_listTables_args&);
  AccumuloProxy_listTables_args() : login() {
  }

  virtual ~AccumuloProxy_listTables_args() throw();
  std::string login;

  _AccumuloProxy_listTables_args__isset __isset;

  void __set_login(const std::string& val);

  bool operator == (const AccumuloProxy_listTables_args & rhs) const
  {
    if (!(login == rhs.login))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_listTables_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_listTables_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_listTables_pargs {
 public:


  virtual ~AccumuloProxy_listTables_pargs() throw();
  const std::string* login;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_listTables_result__isset {
  _AccumuloProxy_listTables_result__isset() : success(false) {}
  bool success :1;
} _AccumuloProxy_listTables_result__isset;

class AccumuloProxy_listTables_result {
 public:

  AccumuloProxy_listTables_result(const AccumuloProxy_listTables_result&);
  AccumuloProxy_listTables_result& operator=(const AccumuloProxy_listTables_result&);
  AccumuloProxy_listTables_result() {
  }

  virtual ~AccumuloProxy_listTables_result() throw();
  std::set<std::string>  success;

  _AccumuloProxy_listTables_result__isset __isset;

  void __set_success(const std::set<std::string> & val);

  bool operator == (const AccumuloProxy_listTables_result & rhs) const
  {
    if (!(success == rhs.success))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_listTables_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_listTables_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_listTables_presult__isset {
  _AccumuloProxy_listTables_presult__isset() : success(false) {}
  bool success :1;
} _AccumuloProxy_listTables_presult__isset;

class AccumuloProxy_listTables_presult {
 public:


  virtual ~AccumuloProxy_listTables_presult() throw();
  std::set<std::string> * success;

  _AccumuloProxy_listTables_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_listIterators_args__isset {
  _AccumuloProxy_listIterators_args__isset() : login(false), tableName(false) {}
  bool login :1;
  bool tableName :1;
} _AccumuloProxy_listIterators_args__isset;

class AccumuloProxy_listIterators_args {
 public:

  AccumuloProxy_listIterators_args(const AccumuloProxy_listIterators_args&);
  AccumuloProxy_listIterators_args& operator=(const AccumuloProxy_listIterators_args&);
  AccumuloProxy_listIterators_args() : login(), tableName() {
  }

  virtual ~AccumuloProxy_listIterators_args() throw();
  std::string login;
  std::string tableName;

  _AccumuloProxy_listIterators_args__isset __isset;

  void __set_login(const std::string& val);

  void __set_tableName(const std::string& val);

  bool operator == (const AccumuloProxy_listIterators_args & rhs) const
  {
    if (!(login == rhs.login))
      return false;
    if (!(tableName == rhs.tableName))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_listIterators_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_listIterators_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_listIterators_pargs {
 public:


  virtual ~AccumuloProxy_listIterators_pargs() throw();
  const std::string* login;
  const std::string* tableName;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_listIterators_result__isset {
  _AccumuloProxy_listIterators_result__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
  bool success :1;
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_listIterators_result__isset;

class AccumuloProxy_listIterators_result {
 public:

  AccumuloProxy_listIterators_result(const AccumuloProxy_listIterators_result&);
  AccumuloProxy_listIterators_result& operator=(const AccumuloProxy_listIterators_result&);
  AccumuloProxy_listIterators_result() {
  }

  virtual ~AccumuloProxy_listIterators_result() throw();
  std::map<std::string, std::set<IteratorScope::type> >  success;
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  TableNotFoundException ouch3;

  _AccumuloProxy_listIterators_result__isset __isset;

  void __set_success(const std::map<std::string, std::set<IteratorScope::type> > & val);

  void __set_ouch1(const AccumuloException& val);

  void __set_ouch2(const AccumuloSecurityException& val);

  void __set_ouch3(const TableNotFoundException& val);

  bool operator == (const AccumuloProxy_listIterators_result & rhs) const
  {
    if (!(success == rhs.success))
      return false;
    if (!(ouch1 == rhs.ouch1))
      return false;
    if (!(ouch2 == rhs.ouch2))
      return false;
    if (!(ouch3 == rhs.ouch3))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_listIterators_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_listIterators_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_listIterators_presult__isset {
  _AccumuloProxy_listIterators_presult__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
  bool success :1;
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_listIterators_presult__isset;

class AccumuloProxy_listIterators_presult {
 public:


  virtual ~AccumuloProxy_listIterators_presult() throw();
  std::map<std::string, std::set<IteratorScope::type> > * success;
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  TableNotFoundException ouch3;

  _AccumuloProxy_listIterators_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_listConstraints_args__isset {
  _AccumuloProxy_listConstraints_args__isset() : login(false), tableName(false) {}
  bool login :1;
  bool tableName :1;
} _AccumuloProxy_listConstraints_args__isset;

class AccumuloProxy_listConstraints_args {
 public:

  AccumuloProxy_listConstraints_args(const AccumuloProxy_listConstraints_args&);
  AccumuloProxy_listConstraints_args& operator=(const AccumuloProxy_listConstraints_args&);
  AccumuloProxy_listConstraints_args() : login(), tableName() {
  }

  virtual ~AccumuloProxy_listConstraints_args() throw();
  std::string login;
  std::string tableName;

  _AccumuloProxy_listConstraints_args__isset __isset;

  void __set_login(const std::string& val);

  void __set_tableName(const std::string& val);

  bool operator == (const AccumuloProxy_listConstraints_args & rhs) const
  {
    if (!(login == rhs.login))
      return false;
    if (!(tableName == rhs.tableName))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_listConstraints_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_listConstraints_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_listConstraints_pargs {
 public:


  virtual ~AccumuloProxy_listConstraints_pargs() throw();
  const std::string* login;
  const std::string* tableName;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_listConstraints_result__isset {
  _AccumuloProxy_listConstraints_result__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
  bool success :1;
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_listConstraints_result__isset;

class AccumuloProxy_listConstraints_result {
 public:

  AccumuloProxy_listConstraints_result(const AccumuloProxy_listConstraints_result&);
  AccumuloProxy_listConstraints_result& operator=(const AccumuloProxy_listConstraints_result&);
  AccumuloProxy_listConstraints_result() {
  }

  virtual ~AccumuloProxy_listConstraints_result() throw();
  std::map<std::string, int32_t>  success;
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  TableNotFoundException ouch3;

  _AccumuloProxy_listConstraints_result__isset __isset;

  void __set_success(const std::map<std::string, int32_t> & val);

  void __set_ouch1(const AccumuloException& val);

  void __set_ouch2(const AccumuloSecurityException& val);

  void __set_ouch3(const TableNotFoundException& val);

  bool operator == (const AccumuloProxy_listConstraints_result & rhs) const
  {
    if (!(success == rhs.success))
      return false;
    if (!(ouch1 == rhs.ouch1))
      return false;
    if (!(ouch2 == rhs.ouch2))
      return false;
    if (!(ouch3 == rhs.ouch3))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_listConstraints_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_listConstraints_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_listConstraints_presult__isset {
  _AccumuloProxy_listConstraints_presult__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
  bool success :1;
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_listConstraints_presult__isset;

class AccumuloProxy_listConstraints_presult {
 public:


  virtual ~AccumuloProxy_listConstraints_presult() throw();
  std::map<std::string, int32_t> * success;
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  TableNotFoundException ouch3;

  _AccumuloProxy_listConstraints_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_mergeTablets_args__isset {
  _AccumuloProxy_mergeTablets_args__isset() : login(false), tableName(false), startRow(false), endRow(false) {}
  bool login :1;
  bool tableName :1;
  bool startRow :1;
  bool endRow :1;
} _AccumuloProxy_mergeTablets_args__isset;

class AccumuloProxy_mergeTablets_args {
 public:

  AccumuloProxy_mergeTablets_args(const AccumuloProxy_mergeTablets_args&);
  AccumuloProxy_mergeTablets_args& operator=(const AccumuloProxy_mergeTablets_args&);
  AccumuloProxy_mergeTablets_args() : login(), tableName(), startRow(), endRow() {
  }

  virtual ~AccumuloProxy_mergeTablets_args() throw();
  std::string login;
  std::string tableName;
  std::string startRow;
  std::string endRow;

  _AccumuloProxy_mergeTablets_args__isset __isset;

  void __set_login(const std::string& val);

  void __set_tableName(const std::string& val);

  void __set_startRow(const std::string& val);

  void __set_endRow(const std::string& val);

  bool operator == (const AccumuloProxy_mergeTablets_args & rhs) const
  {
    if (!(login == rhs.login))
      return false;
    if (!(tableName == rhs.tableName))
      return false;
    if (!(startRow == rhs.startRow))
      return false;
    if (!(endRow == rhs.endRow))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_mergeTablets_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_mergeTablets_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_mergeTablets_pargs {
 public:


  virtual ~AccumuloProxy_mergeTablets_pargs() throw();
  const std::string* login;
  const std::string* tableName;
  const std::string* startRow;
  const std::string* endRow;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_mergeTablets_result__isset {
  _AccumuloProxy_mergeTablets_result__isset() : ouch1(false), ouch2(false), ouch3(false) {}
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_mergeTablets_result__isset;

class AccumuloProxy_mergeTablets_result {
 public:

  AccumuloProxy_mergeTablets_result(const AccumuloProxy_mergeTablets_result&);
  AccumuloProxy_mergeTablets_result& operator=(const AccumuloProxy_mergeTablets_result&);
  AccumuloProxy_mergeTablets_result() {
  }

  virtual ~AccumuloProxy_mergeTablets_result() throw();
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  TableNotFoundException ouch3;

  _AccumuloProxy_mergeTablets_result__isset __isset;

  void __set_ouch1(const AccumuloException& val);

  void __set_ouch2(const AccumuloSecurityException& val);

  void __set_ouch3(const TableNotFoundException& val);

  bool operator == (const AccumuloProxy_mergeTablets_result & rhs) const
  {
    if (!(ouch1 == rhs.ouch1))
      return false;
    if (!(ouch2 == rhs.ouch2))
      return false;
    if (!(ouch3 == rhs.ouch3))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_mergeTablets_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_mergeTablets_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_mergeTablets_presult__isset {
  _AccumuloProxy_mergeTablets_presult__isset() : ouch1(false), ouch2(false), ouch3(false) {}
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_mergeTablets_presult__isset;

class AccumuloProxy_mergeTablets_presult {
 public:


  virtual ~AccumuloProxy_mergeTablets_presult() throw();
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  TableNotFoundException ouch3;

  _AccumuloProxy_mergeTablets_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_offlineTable_args__isset {
  _AccumuloProxy_offlineTable_args__isset() : login(false), tableName(false), wait(true) {}
  bool login :1;
  bool tableName :1;
  bool wait :1;
} _AccumuloProxy_offlineTable_args__isset;

class AccumuloProxy_offlineTable_args {
 public:

  AccumuloProxy_offlineTable_args(const AccumuloProxy_offlineTable_args&);
  AccumuloProxy_offlineTable_args& operator=(const AccumuloProxy_offlineTable_args&);
  AccumuloProxy_offlineTable_args() : login(), tableName(), wait(false) {
  }

  virtual ~AccumuloProxy_offlineTable_args() throw();
  std::string login;
  std::string tableName;
  bool wait;

  _AccumuloProxy_offlineTable_args__isset __isset;

  void __set_login(const std::string& val);

  void __set_tableName(const std::string& val);

  void __set_wait(const bool val);

  bool operator == (const AccumuloProxy_offlineTable_args & rhs) const
  {
    if (!(login == rhs.login))
      return false;
    if (!(tableName == rhs.tableName))
      return false;
    if (!(wait == rhs.wait))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_offlineTable_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_offlineTable_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_offlineTable_pargs {
 public:


  virtual ~AccumuloProxy_offlineTable_pargs() throw();
  const std::string* login;
  const std::string* tableName;
  const bool* wait;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_offlineTable_result__isset {
  _AccumuloProxy_offlineTable_result__isset() : ouch1(false), ouch2(false), ouch3(false) {}
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_offlineTable_result__isset;

class AccumuloProxy_offlineTable_result {
 public:

  AccumuloProxy_offlineTable_result(const AccumuloProxy_offlineTable_result&);
  AccumuloProxy_offlineTable_result& operator=(const AccumuloProxy_offlineTable_result&);
  AccumuloProxy_offlineTable_result() {
  }

  virtual ~AccumuloProxy_offlineTable_result() throw();
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  TableNotFoundException ouch3;

  _AccumuloProxy_offlineTable_result__isset __isset;

  void __set_ouch1(const AccumuloException& val);

  void __set_ouch2(const AccumuloSecurityException& val);

  void __set_ouch3(const TableNotFoundException& val);

  bool operator == (const AccumuloProxy_offlineTable_result & rhs) const
  {
    if (!(ouch1 == rhs.ouch1))
      return false;
    if (!(ouch2 == rhs.ouch2))
      return false;
    if (!(ouch3 == rhs.ouch3))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_offlineTable_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_offlineTable_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_offlineTable_presult__isset {
  _AccumuloProxy_offlineTable_presult__isset() : ouch1(false), ouch2(false), ouch3(false) {}
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_offlineTable_presult__isset;

class AccumuloProxy_offlineTable_presult {
 public:


  virtual ~AccumuloProxy_offlineTable_presult() throw();
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  TableNotFoundException ouch3;

  _AccumuloProxy_offlineTable_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_onlineTable_args__isset {
  _AccumuloProxy_onlineTable_args__isset() : login(false), tableName(false), wait(true) {}
  bool login :1;
  bool tableName :1;
  bool wait :1;
} _AccumuloProxy_onlineTable_args__isset;

class AccumuloProxy_onlineTable_args {
 public:

  AccumuloProxy_onlineTable_args(const AccumuloProxy_onlineTable_args&);
  AccumuloProxy_onlineTable_args& operator=(const AccumuloProxy_onlineTable_args&);
  AccumuloProxy_onlineTable_args() : login(), tableName(), wait(false) {
  }

  virtual ~AccumuloProxy_onlineTable_args() throw();
  std::string login;
  std::string tableName;
  bool wait;

  _AccumuloProxy_onlineTable_args__isset __isset;

  void __set_login(const std::string& val);

  void __set_tableName(const std::string& val);

  void __set_wait(const bool val);

  bool operator == (const AccumuloProxy_onlineTable_args & rhs) const
  {
    if (!(login == rhs.login))
      return false;
    if (!(tableName == rhs.tableName))
      return false;
    if (!(wait == rhs.wait))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_onlineTable_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_onlineTable_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_onlineTable_pargs {
 public:


  virtual ~AccumuloProxy_onlineTable_pargs() throw();
  const std::string* login;
  const std::string* tableName;
  const bool* wait;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_onlineTable_result__isset {
  _AccumuloProxy_onlineTable_result__isset() : ouch1(false), ouch2(false), ouch3(false) {}
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_onlineTable_result__isset;

class AccumuloProxy_onlineTable_result {
 public:

  AccumuloProxy_onlineTable_result(const AccumuloProxy_onlineTable_result&);
  AccumuloProxy_onlineTable_result& operator=(const AccumuloProxy_onlineTable_result&);
  AccumuloProxy_onlineTable_result() {
  }

  virtual ~AccumuloProxy_onlineTable_result() throw();
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  TableNotFoundException ouch3;

  _AccumuloProxy_onlineTable_result__isset __isset;

  void __set_ouch1(const AccumuloException& val);

  void __set_ouch2(const AccumuloSecurityException& val);

  void __set_ouch3(const TableNotFoundException& val);

  bool operator == (const AccumuloProxy_onlineTable_result & rhs) const
  {
    if (!(ouch1 == rhs.ouch1))
      return false;
    if (!(ouch2 == rhs.ouch2))
      return false;
    if (!(ouch3 == rhs.ouch3))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_onlineTable_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_onlineTable_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_onlineTable_presult__isset {
  _AccumuloProxy_onlineTable_presult__isset() : ouch1(false), ouch2(false), ouch3(false) {}
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_onlineTable_presult__isset;

class AccumuloProxy_onlineTable_presult {
 public:


  virtual ~AccumuloProxy_onlineTable_presult() throw();
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  TableNotFoundException ouch3;

  _AccumuloProxy_onlineTable_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_removeConstraint_args__isset {
  _AccumuloProxy_removeConstraint_args__isset() : login(false), tableName(false), constraint(false) {}
  bool login :1;
  bool tableName :1;
  bool constraint :1;
} _AccumuloProxy_removeConstraint_args__isset;

class AccumuloProxy_removeConstraint_args {
 public:

  AccumuloProxy_removeConstraint_args(const AccumuloProxy_removeConstraint_args&);
  AccumuloProxy_removeConstraint_args& operator=(const AccumuloProxy_removeConstraint_args&);
  AccumuloProxy_removeConstraint_args() : login(), tableName(), constraint(0) {
  }

  virtual ~AccumuloProxy_removeConstraint_args() throw();
  std::string login;
  std::string tableName;
  int32_t constraint;

  _AccumuloProxy_removeConstraint_args__isset __isset;

  void __set_login(const std::string& val);

  void __set_tableName(const std::string& val);

  void __set_constraint(const int32_t val);

  bool operator == (const AccumuloProxy_removeConstraint_args & rhs) const
  {
    if (!(login == rhs.login))
      return false;
    if (!(tableName == rhs.tableName))
      return false;
    if (!(constraint == rhs.constraint))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_removeConstraint_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_removeConstraint_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_removeConstraint_pargs {
 public:


  virtual ~AccumuloProxy_removeConstraint_pargs() throw();
  const std::string* login;
  const std::string* tableName;
  const int32_t* constraint;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_removeConstraint_result__isset {
  _AccumuloProxy_removeConstraint_result__isset() : ouch1(false), ouch2(false), ouch3(false) {}
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_removeConstraint_result__isset;

class AccumuloProxy_removeConstraint_result {
 public:

  AccumuloProxy_removeConstraint_result(const AccumuloProxy_removeConstraint_result&);
  AccumuloProxy_removeConstraint_result& operator=(const AccumuloProxy_removeConstraint_result&);
  AccumuloProxy_removeConstraint_result() {
  }

  virtual ~AccumuloProxy_removeConstraint_result() throw();
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  TableNotFoundException ouch3;

  _AccumuloProxy_removeConstraint_result__isset __isset;

  void __set_ouch1(const AccumuloException& val);

  void __set_ouch2(const AccumuloSecurityException& val);

  void __set_ouch3(const TableNotFoundException& val);

  bool operator == (const AccumuloProxy_removeConstraint_result & rhs) const
  {
    if (!(ouch1 == rhs.ouch1))
      return false;
    if (!(ouch2 == rhs.ouch2))
      return false;
    if (!(ouch3 == rhs.ouch3))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_removeConstraint_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_removeConstraint_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_removeConstraint_presult__isset {
  _AccumuloProxy_removeConstraint_presult__isset() : ouch1(false), ouch2(false), ouch3(false) {}
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_removeConstraint_presult__isset;

class AccumuloProxy_removeConstraint_presult {
 public:


  virtual ~AccumuloProxy_removeConstraint_presult() throw();
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  TableNotFoundException ouch3;

  _AccumuloProxy_removeConstraint_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_removeIterator_args__isset {
  _AccumuloProxy_removeIterator_args__isset() : login(false), tableName(false), iterName(false), scopes(false) {}
  bool login :1;
  bool tableName :1;
  bool iterName :1;
  bool scopes :1;
} _AccumuloProxy_removeIterator_args__isset;

class AccumuloProxy_removeIterator_args {
 public:

  AccumuloProxy_removeIterator_args(const AccumuloProxy_removeIterator_args&);
  AccumuloProxy_removeIterator_args& operator=(const AccumuloProxy_removeIterator_args&);
  AccumuloProxy_removeIterator_args() : login(), tableName(), iterName() {
  }

  virtual ~AccumuloProxy_removeIterator_args() throw();
  std::string login;
  std::string tableName;
  std::string iterName;
  std::set<IteratorScope::type>  scopes;

  _AccumuloProxy_removeIterator_args__isset __isset;

  void __set_login(const std::string& val);

  void __set_tableName(const std::string& val);

  void __set_iterName(const std::string& val);

  void __set_scopes(const std::set<IteratorScope::type> & val);

  bool operator == (const AccumuloProxy_removeIterator_args & rhs) const
  {
    if (!(login == rhs.login))
      return false;
    if (!(tableName == rhs.tableName))
      return false;
    if (!(iterName == rhs.iterName))
      return false;
    if (!(scopes == rhs.scopes))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_removeIterator_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_removeIterator_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_removeIterator_pargs {
 public:


  virtual ~AccumuloProxy_removeIterator_pargs() throw();
  const std::string* login;
  const std::string* tableName;
  const std::string* iterName;
  const std::set<IteratorScope::type> * scopes;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_removeIterator_result__isset {
  _AccumuloProxy_removeIterator_result__isset() : ouch1(false), ouch2(false), ouch3(false) {}
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_removeIterator_result__isset;

class AccumuloProxy_removeIterator_result {
 public:

  AccumuloProxy_removeIterator_result(const AccumuloProxy_removeIterator_result&);
  AccumuloProxy_removeIterator_result& operator=(const AccumuloProxy_removeIterator_result&);
  AccumuloProxy_removeIterator_result() {
  }

  virtual ~AccumuloProxy_removeIterator_result() throw();
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  TableNotFoundException ouch3;

  _AccumuloProxy_removeIterator_result__isset __isset;

  void __set_ouch1(const AccumuloException& val);

  void __set_ouch2(const AccumuloSecurityException& val);

  void __set_ouch3(const TableNotFoundException& val);

  bool operator == (const AccumuloProxy_removeIterator_result & rhs) const
  {
    if (!(ouch1 == rhs.ouch1))
      return false;
    if (!(ouch2 == rhs.ouch2))
      return false;
    if (!(ouch3 == rhs.ouch3))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_removeIterator_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_removeIterator_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_removeIterator_presult__isset {
  _AccumuloProxy_removeIterator_presult__isset() : ouch1(false), ouch2(false), ouch3(false) {}
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_removeIterator_presult__isset;

class AccumuloProxy_removeIterator_presult {
 public:


  virtual ~AccumuloProxy_removeIterator_presult() throw();
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  TableNotFoundException ouch3;

  _AccumuloProxy_removeIterator_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_removeTableProperty_args__isset {
  _AccumuloProxy_removeTableProperty_args__isset() : login(false), tableName(false), property(false) {}
  bool login :1;
  bool tableName :1;
  bool property :1;
} _AccumuloProxy_removeTableProperty_args__isset;

class AccumuloProxy_removeTableProperty_args {
 public:

  AccumuloProxy_removeTableProperty_args(const AccumuloProxy_removeTableProperty_args&);
  AccumuloProxy_removeTableProperty_args& operator=(const AccumuloProxy_removeTableProperty_args&);
  AccumuloProxy_removeTableProperty_args() : login(), tableName(), property() {
  }

  virtual ~AccumuloProxy_removeTableProperty_args() throw();
  std::string login;
  std::string tableName;
  std::string property;

  _AccumuloProxy_removeTableProperty_args__isset __isset;

  void __set_login(const std::string& val);

  void __set_tableName(const std::string& val);

  void __set_property(const std::string& val);

  bool operator == (const AccumuloProxy_removeTableProperty_args & rhs) const
  {
    if (!(login == rhs.login))
      return false;
    if (!(tableName == rhs.tableName))
      return false;
    if (!(property == rhs.property))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_removeTableProperty_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_removeTableProperty_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_removeTableProperty_pargs {
 public:


  virtual ~AccumuloProxy_removeTableProperty_pargs() throw();
  const std::string* login;
  const std::string* tableName;
  const std::string* property;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_removeTableProperty_result__isset {
  _AccumuloProxy_removeTableProperty_result__isset() : ouch1(false), ouch2(false), ouch3(false) {}
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_removeTableProperty_result__isset;

class AccumuloProxy_removeTableProperty_result {
 public:

  AccumuloProxy_removeTableProperty_result(const AccumuloProxy_removeTableProperty_result&);
  AccumuloProxy_removeTableProperty_result& operator=(const AccumuloProxy_removeTableProperty_result&);
  AccumuloProxy_removeTableProperty_result() {
  }

  virtual ~AccumuloProxy_removeTableProperty_result() throw();
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  TableNotFoundException ouch3;

  _AccumuloProxy_removeTableProperty_result__isset __isset;

  void __set_ouch1(const AccumuloException& val);

  void __set_ouch2(const AccumuloSecurityException& val);

  void __set_ouch3(const TableNotFoundException& val);

  bool operator == (const AccumuloProxy_removeTableProperty_result & rhs) const
  {
    if (!(ouch1 == rhs.ouch1))
      return false;
    if (!(ouch2 == rhs.ouch2))
      return false;
    if (!(ouch3 == rhs.ouch3))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_removeTableProperty_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_removeTableProperty_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_removeTableProperty_presult__isset {
  _AccumuloProxy_removeTableProperty_presult__isset() : ouch1(false), ouch2(false), ouch3(false) {}
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_removeTableProperty_presult__isset;

class AccumuloProxy_removeTableProperty_presult {
 public:


  virtual ~AccumuloProxy_removeTableProperty_presult() throw();
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  TableNotFoundException ouch3;

  _AccumuloProxy_removeTableProperty_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_renameTable_args__isset {
  _AccumuloProxy_renameTable_args__isset() : login(false), oldTableName(false), newTableName(false) {}
  bool login :1;
  bool oldTableName :1;
  bool newTableName :1;
} _AccumuloProxy_renameTable_args__isset;

class AccumuloProxy_renameTable_args {
 public:

  AccumuloProxy_renameTable_args(const AccumuloProxy_renameTable_args&);
  AccumuloProxy_renameTable_args& operator=(const AccumuloProxy_renameTable_args&);
  AccumuloProxy_renameTable_args() : login(), oldTableName(), newTableName() {
  }

  virtual ~AccumuloProxy_renameTable_args() throw();
  std::string login;
  std::string oldTableName;
  std::string newTableName;

  _AccumuloProxy_renameTable_args__isset __isset;

  void __set_login(const std::string& val);

  void __set_oldTableName(const std::string& val);

  void __set_newTableName(const std::string& val);

  bool operator == (const AccumuloProxy_renameTable_args & rhs) const
  {
    if (!(login == rhs.login))
      return false;
    if (!(oldTableName == rhs.oldTableName))
      return false;
    if (!(newTableName == rhs.newTableName))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_renameTable_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_renameTable_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_renameTable_pargs {
 public:


  virtual ~AccumuloProxy_renameTable_pargs() throw();
  const std::string* login;
  const std::string* oldTableName;
  const std::string* newTableName;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_renameTable_result__isset {
  _AccumuloProxy_renameTable_result__isset() : ouch1(false), ouch2(false), ouch3(false), ouch4(false) {}
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
  bool ouch4 :1;
} _AccumuloProxy_renameTable_result__isset;

class AccumuloProxy_renameTable_result {
 public:

  AccumuloProxy_renameTable_result(const AccumuloProxy_renameTable_result&);
  AccumuloProxy_renameTable_result& operator=(const AccumuloProxy_renameTable_result&);
  AccumuloProxy_renameTable_result() {
  }

  virtual ~AccumuloProxy_renameTable_result() throw();
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  TableNotFoundException ouch3;
  TableExistsException ouch4;

  _AccumuloProxy_renameTable_result__isset __isset;

  void __set_ouch1(const AccumuloException& val);

  void __set_ouch2(const AccumuloSecurityException& val);

  void __set_ouch3(const TableNotFoundException& val);

  void __set_ouch4(const TableExistsException& val);

  bool operator == (const AccumuloProxy_renameTable_result & rhs) const
  {
    if (!(ouch1 == rhs.ouch1))
      return false;
    if (!(ouch2 == rhs.ouch2))
      return false;
    if (!(ouch3 == rhs.ouch3))
      return false;
    if (!(ouch4 == rhs.ouch4))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_renameTable_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_renameTable_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_renameTable_presult__isset {
  _AccumuloProxy_renameTable_presult__isset() : ouch1(false), ouch2(false), ouch3(false), ouch4(false) {}
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
  bool ouch4 :1;
} _AccumuloProxy_renameTable_presult__isset;

class AccumuloProxy_renameTable_presult {
 public:


  virtual ~AccumuloProxy_renameTable_presult() throw();
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  TableNotFoundException ouch3;
  TableExistsException ouch4;

  _AccumuloProxy_renameTable_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_setLocalityGroups_args__isset {
  _AccumuloProxy_setLocalityGroups_args__isset() : login(false), tableName(false), groups(false) {}
  bool login :1;
  bool tableName :1;
  bool groups :1;
} _AccumuloProxy_setLocalityGroups_args__isset;

class AccumuloProxy_setLocalityGroups_args {
 public:

  AccumuloProxy_setLocalityGroups_args(const AccumuloProxy_setLocalityGroups_args&);
  AccumuloProxy_setLocalityGroups_args& operator=(const AccumuloProxy_setLocalityGroups_args&);
  AccumuloProxy_setLocalityGroups_args() : login(), tableName() {
  }

  virtual ~AccumuloProxy_setLocalityGroups_args() throw();
  std::string login;
  std::string tableName;
  std::map<std::string, std::set<std::string> >  groups;

  _AccumuloProxy_setLocalityGroups_args__isset __isset;

  void __set_login(const std::string& val);

  void __set_tableName(const std::string& val);

  void __set_groups(const std::map<std::string, std::set<std::string> > & val);

  bool operator == (const AccumuloProxy_setLocalityGroups_args & rhs) const
  {
    if (!(login == rhs.login))
      return false;
    if (!(tableName == rhs.tableName))
      return false;
    if (!(groups == rhs.groups))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_setLocalityGroups_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_setLocalityGroups_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_setLocalityGroups_pargs {
 public:


  virtual ~AccumuloProxy_setLocalityGroups_pargs() throw();
  const std::string* login;
  const std::string* tableName;
  const std::map<std::string, std::set<std::string> > * groups;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_setLocalityGroups_result__isset {
  _AccumuloProxy_setLocalityGroups_result__isset() : ouch1(false), ouch2(false), ouch3(false) {}
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_setLocalityGroups_result__isset;

class AccumuloProxy_setLocalityGroups_result {
 public:

  AccumuloProxy_setLocalityGroups_result(const AccumuloProxy_setLocalityGroups_result&);
  AccumuloProxy_setLocalityGroups_result& operator=(const AccumuloProxy_setLocalityGroups_result&);
  AccumuloProxy_setLocalityGroups_result() {
  }

  virtual ~AccumuloProxy_setLocalityGroups_result() throw();
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  TableNotFoundException ouch3;

  _AccumuloProxy_setLocalityGroups_result__isset __isset;

  void __set_ouch1(const AccumuloException& val);

  void __set_ouch2(const AccumuloSecurityException& val);

  void __set_ouch3(const TableNotFoundException& val);

  bool operator == (const AccumuloProxy_setLocalityGroups_result & rhs) const
  {
    if (!(ouch1 == rhs.ouch1))
      return false;
    if (!(ouch2 == rhs.ouch2))
      return false;
    if (!(ouch3 == rhs.ouch3))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_setLocalityGroups_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_setLocalityGroups_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_setLocalityGroups_presult__isset {
  _AccumuloProxy_setLocalityGroups_presult__isset() : ouch1(false), ouch2(false), ouch3(false) {}
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_setLocalityGroups_presult__isset;

class AccumuloProxy_setLocalityGroups_presult {
 public:


  virtual ~AccumuloProxy_setLocalityGroups_presult() throw();
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  TableNotFoundException ouch3;

  _AccumuloProxy_setLocalityGroups_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_setTableProperty_args__isset {
  _AccumuloProxy_setTableProperty_args__isset() : login(false), tableName(false), property(false), value(false) {}
  bool login :1;
  bool tableName :1;
  bool property :1;
  bool value :1;
} _AccumuloProxy_setTableProperty_args__isset;

class AccumuloProxy_setTableProperty_args {
 public:

  AccumuloProxy_setTableProperty_args(const AccumuloProxy_setTableProperty_args&);
  AccumuloProxy_setTableProperty_args& operator=(const AccumuloProxy_setTableProperty_args&);
  AccumuloProxy_setTableProperty_args() : login(), tableName(), property(), value() {
  }

  virtual ~AccumuloProxy_setTableProperty_args() throw();
  std::string login;
  std::string tableName;
  std::string property;
  std::string value;

  _AccumuloProxy_setTableProperty_args__isset __isset;

  void __set_login(const std::string& val);

  void __set_tableName(const std::string& val);

  void __set_property(const std::string& val);

  void __set_value(const std::string& val);

  bool operator == (const AccumuloProxy_setTableProperty_args & rhs) const
  {
    if (!(login == rhs.login))
      return false;
    if (!(tableName == rhs.tableName))
      return false;
    if (!(property == rhs.property))
      return false;
    if (!(value == rhs.value))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_setTableProperty_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_setTableProperty_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_setTableProperty_pargs {
 public:


  virtual ~AccumuloProxy_setTableProperty_pargs() throw();
  const std::string* login;
  const std::string* tableName;
  const std::string* property;
  const std::string* value;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_setTableProperty_result__isset {
  _AccumuloProxy_setTableProperty_result__isset() : ouch1(false), ouch2(false), ouch3(false) {}
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_setTableProperty_result__isset;

class AccumuloProxy_setTableProperty_result {
 public:

  AccumuloProxy_setTableProperty_result(const AccumuloProxy_setTableProperty_result&);
  AccumuloProxy_setTableProperty_result& operator=(const AccumuloProxy_setTableProperty_result&);
  AccumuloProxy_setTableProperty_result() {
  }

  virtual ~AccumuloProxy_setTableProperty_result() throw();
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  TableNotFoundException ouch3;

  _AccumuloProxy_setTableProperty_result__isset __isset;

  void __set_ouch1(const AccumuloException& val);

  void __set_ouch2(const AccumuloSecurityException& val);

  void __set_ouch3(const TableNotFoundException& val);

  bool operator == (const AccumuloProxy_setTableProperty_result & rhs) const
  {
    if (!(ouch1 == rhs.ouch1))
      return false;
    if (!(ouch2 == rhs.ouch2))
      return false;
    if (!(ouch3 == rhs.ouch3))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_setTableProperty_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_setTableProperty_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_setTableProperty_presult__isset {
  _AccumuloProxy_setTableProperty_presult__isset() : ouch1(false), ouch2(false), ouch3(false) {}
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_setTableProperty_presult__isset;

class AccumuloProxy_setTableProperty_presult {
 public:


  virtual ~AccumuloProxy_setTableProperty_presult() throw();
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  TableNotFoundException ouch3;

  _AccumuloProxy_setTableProperty_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_splitRangeByTablets_args__isset {
  _AccumuloProxy_splitRangeByTablets_args__isset() : login(false), tableName(false), range(false), maxSplits(false) {}
  bool login :1;
  bool tableName :1;
  bool range :1;
  bool maxSplits :1;
} _AccumuloProxy_splitRangeByTablets_args__isset;

class AccumuloProxy_splitRangeByTablets_args {
 public:

  AccumuloProxy_splitRangeByTablets_args(const AccumuloProxy_splitRangeByTablets_args&);
  AccumuloProxy_splitRangeByTablets_args& operator=(const AccumuloProxy_splitRangeByTablets_args&);
  AccumuloProxy_splitRangeByTablets_args() : login(), tableName(), maxSplits(0) {
  }

  virtual ~AccumuloProxy_splitRangeByTablets_args() throw();
  std::string login;
  std::string tableName;
  Range range;
  int32_t maxSplits;

  _AccumuloProxy_splitRangeByTablets_args__isset __isset;

  void __set_login(const std::string& val);

  void __set_tableName(const std::string& val);

  void __set_range(const Range& val);

  void __set_maxSplits(const int32_t val);

  bool operator == (const AccumuloProxy_splitRangeByTablets_args & rhs) const
  {
    if (!(login == rhs.login))
      return false;
    if (!(tableName == rhs.tableName))
      return false;
    if (!(range == rhs.range))
      return false;
    if (!(maxSplits == rhs.maxSplits))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_splitRangeByTablets_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_splitRangeByTablets_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_splitRangeByTablets_pargs {
 public:


  virtual ~AccumuloProxy_splitRangeByTablets_pargs() throw();
  const std::string* login;
  const std::string* tableName;
  const Range* range;
  const int32_t* maxSplits;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_splitRangeByTablets_result__isset {
  _AccumuloProxy_splitRangeByTablets_result__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
  bool success :1;
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_splitRangeByTablets_result__isset;

class AccumuloProxy_splitRangeByTablets_result {
 public:

  AccumuloProxy_splitRangeByTablets_result(const AccumuloProxy_splitRangeByTablets_result&);
  AccumuloProxy_splitRangeByTablets_result& operator=(const AccumuloProxy_splitRangeByTablets_result&);
  AccumuloProxy_splitRangeByTablets_result() {
  }

  virtual ~AccumuloProxy_splitRangeByTablets_result() throw();
  std::set<Range>  success;
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  TableNotFoundException ouch3;

  _AccumuloProxy_splitRangeByTablets_result__isset __isset;

  void __set_success(const std::set<Range> & val);

  void __set_ouch1(const AccumuloException& val);

  void __set_ouch2(const AccumuloSecurityException& val);

  void __set_ouch3(const TableNotFoundException& val);

  bool operator == (const AccumuloProxy_splitRangeByTablets_result & rhs) const
  {
    if (!(success == rhs.success))
      return false;
    if (!(ouch1 == rhs.ouch1))
      return false;
    if (!(ouch2 == rhs.ouch2))
      return false;
    if (!(ouch3 == rhs.ouch3))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_splitRangeByTablets_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_splitRangeByTablets_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_splitRangeByTablets_presult__isset {
  _AccumuloProxy_splitRangeByTablets_presult__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
  bool success :1;
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_splitRangeByTablets_presult__isset;

class AccumuloProxy_splitRangeByTablets_presult {
 public:


  virtual ~AccumuloProxy_splitRangeByTablets_presult() throw();
  std::set<Range> * success;
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  TableNotFoundException ouch3;

  _AccumuloProxy_splitRangeByTablets_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_tableExists_args__isset {
  _AccumuloProxy_tableExists_args__isset() : login(false), tableName(false) {}
  bool login :1;
  bool tableName :1;
} _AccumuloProxy_tableExists_args__isset;

class AccumuloProxy_tableExists_args {
 public:

  AccumuloProxy_tableExists_args(const AccumuloProxy_tableExists_args&);
  AccumuloProxy_tableExists_args& operator=(const AccumuloProxy_tableExists_args&);
  AccumuloProxy_tableExists_args() : login(), tableName() {
  }

  virtual ~AccumuloProxy_tableExists_args() throw();
  std::string login;
  std::string tableName;

  _AccumuloProxy_tableExists_args__isset __isset;

  void __set_login(const std::string& val);

  void __set_tableName(const std::string& val);

  bool operator == (const AccumuloProxy_tableExists_args & rhs) const
  {
    if (!(login == rhs.login))
      return false;
    if (!(tableName == rhs.tableName))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_tableExists_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_tableExists_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_tableExists_pargs {
 public:


  virtual ~AccumuloProxy_tableExists_pargs() throw();
  const std::string* login;
  const std::string* tableName;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_tableExists_result__isset {
  _AccumuloProxy_tableExists_result__isset() : success(false) {}
  bool success :1;
} _AccumuloProxy_tableExists_result__isset;

class AccumuloProxy_tableExists_result {
 public:

  AccumuloProxy_tableExists_result(const AccumuloProxy_tableExists_result&);
  AccumuloProxy_tableExists_result& operator=(const AccumuloProxy_tableExists_result&);
  AccumuloProxy_tableExists_result() : success(0) {
  }

  virtual ~AccumuloProxy_tableExists_result() throw();
  bool success;

  _AccumuloProxy_tableExists_result__isset __isset;

  void __set_success(const bool val);

  bool operator == (const AccumuloProxy_tableExists_result & rhs) const
  {
    if (!(success == rhs.success))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_tableExists_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_tableExists_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_tableExists_presult__isset {
  _AccumuloProxy_tableExists_presult__isset() : success(false) {}
  bool success :1;
} _AccumuloProxy_tableExists_presult__isset;

class AccumuloProxy_tableExists_presult {
 public:


  virtual ~AccumuloProxy_tableExists_presult() throw();
  bool* success;

  _AccumuloProxy_tableExists_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_tableIdMap_args__isset {
  _AccumuloProxy_tableIdMap_args__isset() : login(false) {}
  bool login :1;
} _AccumuloProxy_tableIdMap_args__isset;

class AccumuloProxy_tableIdMap_args {
 public:

  AccumuloProxy_tableIdMap_args(const AccumuloProxy_tableIdMap_args&);
  AccumuloProxy_tableIdMap_args& operator=(const AccumuloProxy_tableIdMap_args&);
  AccumuloProxy_tableIdMap_args() : login() {
  }

  virtual ~AccumuloProxy_tableIdMap_args() throw();
  std::string login;

  _AccumuloProxy_tableIdMap_args__isset __isset;

  void __set_login(const std::string& val);

  bool operator == (const AccumuloProxy_tableIdMap_args & rhs) const
  {
    if (!(login == rhs.login))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_tableIdMap_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_tableIdMap_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_tableIdMap_pargs {
 public:


  virtual ~AccumuloProxy_tableIdMap_pargs() throw();
  const std::string* login;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_tableIdMap_result__isset {
  _AccumuloProxy_tableIdMap_result__isset() : success(false) {}
  bool success :1;
} _AccumuloProxy_tableIdMap_result__isset;

class AccumuloProxy_tableIdMap_result {
 public:

  AccumuloProxy_tableIdMap_result(const AccumuloProxy_tableIdMap_result&);
  AccumuloProxy_tableIdMap_result& operator=(const AccumuloProxy_tableIdMap_result&);
  AccumuloProxy_tableIdMap_result() {
  }

  virtual ~AccumuloProxy_tableIdMap_result() throw();
  std::map<std::string, std::string>  success;

  _AccumuloProxy_tableIdMap_result__isset __isset;

  void __set_success(const std::map<std::string, std::string> & val);

  bool operator == (const AccumuloProxy_tableIdMap_result & rhs) const
  {
    if (!(success == rhs.success))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_tableIdMap_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_tableIdMap_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_tableIdMap_presult__isset {
  _AccumuloProxy_tableIdMap_presult__isset() : success(false) {}
  bool success :1;
} _AccumuloProxy_tableIdMap_presult__isset;

class AccumuloProxy_tableIdMap_presult {
 public:


  virtual ~AccumuloProxy_tableIdMap_presult() throw();
  std::map<std::string, std::string> * success;

  _AccumuloProxy_tableIdMap_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_testTableClassLoad_args__isset {
  _AccumuloProxy_testTableClassLoad_args__isset() : login(false), tableName(false), className(false), asTypeName(false) {}
  bool login :1;
  bool tableName :1;
  bool className :1;
  bool asTypeName :1;
} _AccumuloProxy_testTableClassLoad_args__isset;

class AccumuloProxy_testTableClassLoad_args {
 public:

  AccumuloProxy_testTableClassLoad_args(const AccumuloProxy_testTableClassLoad_args&);
  AccumuloProxy_testTableClassLoad_args& operator=(const AccumuloProxy_testTableClassLoad_args&);
  AccumuloProxy_testTableClassLoad_args() : login(), tableName(), className(), asTypeName() {
  }

  virtual ~AccumuloProxy_testTableClassLoad_args() throw();
  std::string login;
  std::string tableName;
  std::string className;
  std::string asTypeName;

  _AccumuloProxy_testTableClassLoad_args__isset __isset;

  void __set_login(const std::string& val);

  void __set_tableName(const std::string& val);

  void __set_className(const std::string& val);

  void __set_asTypeName(const std::string& val);

  bool operator == (const AccumuloProxy_testTableClassLoad_args & rhs) const
  {
    if (!(login == rhs.login))
      return false;
    if (!(tableName == rhs.tableName))
      return false;
    if (!(className == rhs.className))
      return false;
    if (!(asTypeName == rhs.asTypeName))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_testTableClassLoad_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_testTableClassLoad_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_testTableClassLoad_pargs {
 public:


  virtual ~AccumuloProxy_testTableClassLoad_pargs() throw();
  const std::string* login;
  const std::string* tableName;
  const std::string* className;
  const std::string* asTypeName;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_testTableClassLoad_result__isset {
  _AccumuloProxy_testTableClassLoad_result__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
  bool success :1;
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_testTableClassLoad_result__isset;

class AccumuloProxy_testTableClassLoad_result {
 public:

  AccumuloProxy_testTableClassLoad_result(const AccumuloProxy_testTableClassLoad_result&);
  AccumuloProxy_testTableClassLoad_result& operator=(const AccumuloProxy_testTableClassLoad_result&);
  AccumuloProxy_testTableClassLoad_result() : success(0) {
  }

  virtual ~AccumuloProxy_testTableClassLoad_result() throw();
  bool success;
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  TableNotFoundException ouch3;

  _AccumuloProxy_testTableClassLoad_result__isset __isset;

  void __set_success(const bool val);

  void __set_ouch1(const AccumuloException& val);

  void __set_ouch2(const AccumuloSecurityException& val);

  void __set_ouch3(const TableNotFoundException& val);

  bool operator == (const AccumuloProxy_testTableClassLoad_result & rhs) const
  {
    if (!(success == rhs.success))
      return false;
    if (!(ouch1 == rhs.ouch1))
      return false;
    if (!(ouch2 == rhs.ouch2))
      return false;
    if (!(ouch3 == rhs.ouch3))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_testTableClassLoad_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_testTableClassLoad_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_testTableClassLoad_presult__isset {
  _AccumuloProxy_testTableClassLoad_presult__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
  bool success :1;
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_testTableClassLoad_presult__isset;

class AccumuloProxy_testTableClassLoad_presult {
 public:


  virtual ~AccumuloProxy_testTableClassLoad_presult() throw();
  bool* success;
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  TableNotFoundException ouch3;

  _AccumuloProxy_testTableClassLoad_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_pingTabletServer_args__isset {
  _AccumuloProxy_pingTabletServer_args__isset() : login(false), tserver(false) {}
  bool login :1;
  bool tserver :1;
} _AccumuloProxy_pingTabletServer_args__isset;

class AccumuloProxy_pingTabletServer_args {
 public:

  AccumuloProxy_pingTabletServer_args(const AccumuloProxy_pingTabletServer_args&);
  AccumuloProxy_pingTabletServer_args& operator=(const AccumuloProxy_pingTabletServer_args&);
  AccumuloProxy_pingTabletServer_args() : login(), tserver() {
  }

  virtual ~AccumuloProxy_pingTabletServer_args() throw();
  std::string login;
  std::string tserver;

  _AccumuloProxy_pingTabletServer_args__isset __isset;

  void __set_login(const std::string& val);

  void __set_tserver(const std::string& val);

  bool operator == (const AccumuloProxy_pingTabletServer_args & rhs) const
  {
    if (!(login == rhs.login))
      return false;
    if (!(tserver == rhs.tserver))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_pingTabletServer_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_pingTabletServer_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_pingTabletServer_pargs {
 public:


  virtual ~AccumuloProxy_pingTabletServer_pargs() throw();
  const std::string* login;
  const std::string* tserver;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_pingTabletServer_result__isset {
  _AccumuloProxy_pingTabletServer_result__isset() : ouch1(false), ouch2(false) {}
  bool ouch1 :1;
  bool ouch2 :1;
} _AccumuloProxy_pingTabletServer_result__isset;

class AccumuloProxy_pingTabletServer_result {
 public:

  AccumuloProxy_pingTabletServer_result(const AccumuloProxy_pingTabletServer_result&);
  AccumuloProxy_pingTabletServer_result& operator=(const AccumuloProxy_pingTabletServer_result&);
  AccumuloProxy_pingTabletServer_result() {
  }

  virtual ~AccumuloProxy_pingTabletServer_result() throw();
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;

  _AccumuloProxy_pingTabletServer_result__isset __isset;

  void __set_ouch1(const AccumuloException& val);

  void __set_ouch2(const AccumuloSecurityException& val);

  bool operator == (const AccumuloProxy_pingTabletServer_result & rhs) const
  {
    if (!(ouch1 == rhs.ouch1))
      return false;
    if (!(ouch2 == rhs.ouch2))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_pingTabletServer_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_pingTabletServer_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_pingTabletServer_presult__isset {
  _AccumuloProxy_pingTabletServer_presult__isset() : ouch1(false), ouch2(false) {}
  bool ouch1 :1;
  bool ouch2 :1;
} _AccumuloProxy_pingTabletServer_presult__isset;

class AccumuloProxy_pingTabletServer_presult {
 public:


  virtual ~AccumuloProxy_pingTabletServer_presult() throw();
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;

  _AccumuloProxy_pingTabletServer_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_getActiveScans_args__isset {
  _AccumuloProxy_getActiveScans_args__isset() : login(false), tserver(false) {}
  bool login :1;
  bool tserver :1;
} _AccumuloProxy_getActiveScans_args__isset;

class AccumuloProxy_getActiveScans_args {
 public:

  AccumuloProxy_getActiveScans_args(const AccumuloProxy_getActiveScans_args&);
  AccumuloProxy_getActiveScans_args& operator=(const AccumuloProxy_getActiveScans_args&);
  AccumuloProxy_getActiveScans_args() : login(), tserver() {
  }

  virtual ~AccumuloProxy_getActiveScans_args() throw();
  std::string login;
  std::string tserver;

  _AccumuloProxy_getActiveScans_args__isset __isset;

  void __set_login(const std::string& val);

  void __set_tserver(const std::string& val);

  bool operator == (const AccumuloProxy_getActiveScans_args & rhs) const
  {
    if (!(login == rhs.login))
      return false;
    if (!(tserver == rhs.tserver))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_getActiveScans_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_getActiveScans_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_getActiveScans_pargs {
 public:


  virtual ~AccumuloProxy_getActiveScans_pargs() throw();
  const std::string* login;
  const std::string* tserver;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_getActiveScans_result__isset {
  _AccumuloProxy_getActiveScans_result__isset() : success(false), ouch1(false), ouch2(false) {}
  bool success :1;
  bool ouch1 :1;
  bool ouch2 :1;
} _AccumuloProxy_getActiveScans_result__isset;

class AccumuloProxy_getActiveScans_result {
 public:

  AccumuloProxy_getActiveScans_result(const AccumuloProxy_getActiveScans_result&);
  AccumuloProxy_getActiveScans_result& operator=(const AccumuloProxy_getActiveScans_result&);
  AccumuloProxy_getActiveScans_result() {
  }

  virtual ~AccumuloProxy_getActiveScans_result() throw();
  std::vector<ActiveScan>  success;
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;

  _AccumuloProxy_getActiveScans_result__isset __isset;

  void __set_success(const std::vector<ActiveScan> & val);

  void __set_ouch1(const AccumuloException& val);

  void __set_ouch2(const AccumuloSecurityException& val);

  bool operator == (const AccumuloProxy_getActiveScans_result & rhs) const
  {
    if (!(success == rhs.success))
      return false;
    if (!(ouch1 == rhs.ouch1))
      return false;
    if (!(ouch2 == rhs.ouch2))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_getActiveScans_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_getActiveScans_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_getActiveScans_presult__isset {
  _AccumuloProxy_getActiveScans_presult__isset() : success(false), ouch1(false), ouch2(false) {}
  bool success :1;
  bool ouch1 :1;
  bool ouch2 :1;
} _AccumuloProxy_getActiveScans_presult__isset;

class AccumuloProxy_getActiveScans_presult {
 public:


  virtual ~AccumuloProxy_getActiveScans_presult() throw();
  std::vector<ActiveScan> * success;
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;

  _AccumuloProxy_getActiveScans_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_getActiveCompactions_args__isset {
  _AccumuloProxy_getActiveCompactions_args__isset() : login(false), tserver(false) {}
  bool login :1;
  bool tserver :1;
} _AccumuloProxy_getActiveCompactions_args__isset;

class AccumuloProxy_getActiveCompactions_args {
 public:

  AccumuloProxy_getActiveCompactions_args(const AccumuloProxy_getActiveCompactions_args&);
  AccumuloProxy_getActiveCompactions_args& operator=(const AccumuloProxy_getActiveCompactions_args&);
  AccumuloProxy_getActiveCompactions_args() : login(), tserver() {
  }

  virtual ~AccumuloProxy_getActiveCompactions_args() throw();
  std::string login;
  std::string tserver;

  _AccumuloProxy_getActiveCompactions_args__isset __isset;

  void __set_login(const std::string& val);

  void __set_tserver(const std::string& val);

  bool operator == (const AccumuloProxy_getActiveCompactions_args & rhs) const
  {
    if (!(login == rhs.login))
      return false;
    if (!(tserver == rhs.tserver))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_getActiveCompactions_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_getActiveCompactions_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_getActiveCompactions_pargs {
 public:


  virtual ~AccumuloProxy_getActiveCompactions_pargs() throw();
  const std::string* login;
  const std::string* tserver;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_getActiveCompactions_result__isset {
  _AccumuloProxy_getActiveCompactions_result__isset() : success(false), ouch1(false), ouch2(false) {}
  bool success :1;
  bool ouch1 :1;
  bool ouch2 :1;
} _AccumuloProxy_getActiveCompactions_result__isset;

class AccumuloProxy_getActiveCompactions_result {
 public:

  AccumuloProxy_getActiveCompactions_result(const AccumuloProxy_getActiveCompactions_result&);
  AccumuloProxy_getActiveCompactions_result& operator=(const AccumuloProxy_getActiveCompactions_result&);
  AccumuloProxy_getActiveCompactions_result() {
  }

  virtual ~AccumuloProxy_getActiveCompactions_result() throw();
  std::vector<ActiveCompaction>  success;
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;

  _AccumuloProxy_getActiveCompactions_result__isset __isset;

  void __set_success(const std::vector<ActiveCompaction> & val);

  void __set_ouch1(const AccumuloException& val);

  void __set_ouch2(const AccumuloSecurityException& val);

  bool operator == (const AccumuloProxy_getActiveCompactions_result & rhs) const
  {
    if (!(success == rhs.success))
      return false;
    if (!(ouch1 == rhs.ouch1))
      return false;
    if (!(ouch2 == rhs.ouch2))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_getActiveCompactions_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_getActiveCompactions_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_getActiveCompactions_presult__isset {
  _AccumuloProxy_getActiveCompactions_presult__isset() : success(false), ouch1(false), ouch2(false) {}
  bool success :1;
  bool ouch1 :1;
  bool ouch2 :1;
} _AccumuloProxy_getActiveCompactions_presult__isset;

class AccumuloProxy_getActiveCompactions_presult {
 public:


  virtual ~AccumuloProxy_getActiveCompactions_presult() throw();
  std::vector<ActiveCompaction> * success;
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;

  _AccumuloProxy_getActiveCompactions_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_getSiteConfiguration_args__isset {
  _AccumuloProxy_getSiteConfiguration_args__isset() : login(false) {}
  bool login :1;
} _AccumuloProxy_getSiteConfiguration_args__isset;

class AccumuloProxy_getSiteConfiguration_args {
 public:

  AccumuloProxy_getSiteConfiguration_args(const AccumuloProxy_getSiteConfiguration_args&);
  AccumuloProxy_getSiteConfiguration_args& operator=(const AccumuloProxy_getSiteConfiguration_args&);
  AccumuloProxy_getSiteConfiguration_args() : login() {
  }

  virtual ~AccumuloProxy_getSiteConfiguration_args() throw();
  std::string login;

  _AccumuloProxy_getSiteConfiguration_args__isset __isset;

  void __set_login(const std::string& val);

  bool operator == (const AccumuloProxy_getSiteConfiguration_args & rhs) const
  {
    if (!(login == rhs.login))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_getSiteConfiguration_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_getSiteConfiguration_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_getSiteConfiguration_pargs {
 public:


  virtual ~AccumuloProxy_getSiteConfiguration_pargs() throw();
  const std::string* login;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_getSiteConfiguration_result__isset {
  _AccumuloProxy_getSiteConfiguration_result__isset() : success(false), ouch1(false), ouch2(false) {}
  bool success :1;
  bool ouch1 :1;
  bool ouch2 :1;
} _AccumuloProxy_getSiteConfiguration_result__isset;

class AccumuloProxy_getSiteConfiguration_result {
 public:

  AccumuloProxy_getSiteConfiguration_result(const AccumuloProxy_getSiteConfiguration_result&);
  AccumuloProxy_getSiteConfiguration_result& operator=(const AccumuloProxy_getSiteConfiguration_result&);
  AccumuloProxy_getSiteConfiguration_result() {
  }

  virtual ~AccumuloProxy_getSiteConfiguration_result() throw();
  std::map<std::string, std::string>  success;
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;

  _AccumuloProxy_getSiteConfiguration_result__isset __isset;

  void __set_success(const std::map<std::string, std::string> & val);

  void __set_ouch1(const AccumuloException& val);

  void __set_ouch2(const AccumuloSecurityException& val);

  bool operator == (const AccumuloProxy_getSiteConfiguration_result & rhs) const
  {
    if (!(success == rhs.success))
      return false;
    if (!(ouch1 == rhs.ouch1))
      return false;
    if (!(ouch2 == rhs.ouch2))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_getSiteConfiguration_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_getSiteConfiguration_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_getSiteConfiguration_presult__isset {
  _AccumuloProxy_getSiteConfiguration_presult__isset() : success(false), ouch1(false), ouch2(false) {}
  bool success :1;
  bool ouch1 :1;
  bool ouch2 :1;
} _AccumuloProxy_getSiteConfiguration_presult__isset;

class AccumuloProxy_getSiteConfiguration_presult {
 public:


  virtual ~AccumuloProxy_getSiteConfiguration_presult() throw();
  std::map<std::string, std::string> * success;
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;

  _AccumuloProxy_getSiteConfiguration_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_getSystemConfiguration_args__isset {
  _AccumuloProxy_getSystemConfiguration_args__isset() : login(false) {}
  bool login :1;
} _AccumuloProxy_getSystemConfiguration_args__isset;

class AccumuloProxy_getSystemConfiguration_args {
 public:

  AccumuloProxy_getSystemConfiguration_args(const AccumuloProxy_getSystemConfiguration_args&);
  AccumuloProxy_getSystemConfiguration_args& operator=(const AccumuloProxy_getSystemConfiguration_args&);
  AccumuloProxy_getSystemConfiguration_args() : login() {
  }

  virtual ~AccumuloProxy_getSystemConfiguration_args() throw();
  std::string login;

  _AccumuloProxy_getSystemConfiguration_args__isset __isset;

  void __set_login(const std::string& val);

  bool operator == (const AccumuloProxy_getSystemConfiguration_args & rhs) const
  {
    if (!(login == rhs.login))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_getSystemConfiguration_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_getSystemConfiguration_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_getSystemConfiguration_pargs {
 public:


  virtual ~AccumuloProxy_getSystemConfiguration_pargs() throw();
  const std::string* login;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_getSystemConfiguration_result__isset {
  _AccumuloProxy_getSystemConfiguration_result__isset() : success(false), ouch1(false), ouch2(false) {}
  bool success :1;
  bool ouch1 :1;
  bool ouch2 :1;
} _AccumuloProxy_getSystemConfiguration_result__isset;

class AccumuloProxy_getSystemConfiguration_result {
 public:

  AccumuloProxy_getSystemConfiguration_result(const AccumuloProxy_getSystemConfiguration_result&);
  AccumuloProxy_getSystemConfiguration_result& operator=(const AccumuloProxy_getSystemConfiguration_result&);
  AccumuloProxy_getSystemConfiguration_result() {
  }

  virtual ~AccumuloProxy_getSystemConfiguration_result() throw();
  std::map<std::string, std::string>  success;
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;

  _AccumuloProxy_getSystemConfiguration_result__isset __isset;

  void __set_success(const std::map<std::string, std::string> & val);

  void __set_ouch1(const AccumuloException& val);

  void __set_ouch2(const AccumuloSecurityException& val);

  bool operator == (const AccumuloProxy_getSystemConfiguration_result & rhs) const
  {
    if (!(success == rhs.success))
      return false;
    if (!(ouch1 == rhs.ouch1))
      return false;
    if (!(ouch2 == rhs.ouch2))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_getSystemConfiguration_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_getSystemConfiguration_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_getSystemConfiguration_presult__isset {
  _AccumuloProxy_getSystemConfiguration_presult__isset() : success(false), ouch1(false), ouch2(false) {}
  bool success :1;
  bool ouch1 :1;
  bool ouch2 :1;
} _AccumuloProxy_getSystemConfiguration_presult__isset;

class AccumuloProxy_getSystemConfiguration_presult {
 public:


  virtual ~AccumuloProxy_getSystemConfiguration_presult() throw();
  std::map<std::string, std::string> * success;
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;

  _AccumuloProxy_getSystemConfiguration_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_getTabletServers_args__isset {
  _AccumuloProxy_getTabletServers_args__isset() : login(false) {}
  bool login :1;
} _AccumuloProxy_getTabletServers_args__isset;

class AccumuloProxy_getTabletServers_args {
 public:

  AccumuloProxy_getTabletServers_args(const AccumuloProxy_getTabletServers_args&);
  AccumuloProxy_getTabletServers_args& operator=(const AccumuloProxy_getTabletServers_args&);
  AccumuloProxy_getTabletServers_args() : login() {
  }

  virtual ~AccumuloProxy_getTabletServers_args() throw();
  std::string login;

  _AccumuloProxy_getTabletServers_args__isset __isset;

  void __set_login(const std::string& val);

  bool operator == (const AccumuloProxy_getTabletServers_args & rhs) const
  {
    if (!(login == rhs.login))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_getTabletServers_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_getTabletServers_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_getTabletServers_pargs {
 public:


  virtual ~AccumuloProxy_getTabletServers_pargs() throw();
  const std::string* login;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_getTabletServers_result__isset {
  _AccumuloProxy_getTabletServers_result__isset() : success(false) {}
  bool success :1;
} _AccumuloProxy_getTabletServers_result__isset;

class AccumuloProxy_getTabletServers_result {
 public:

  AccumuloProxy_getTabletServers_result(const AccumuloProxy_getTabletServers_result&);
  AccumuloProxy_getTabletServers_result& operator=(const AccumuloProxy_getTabletServers_result&);
  AccumuloProxy_getTabletServers_result() {
  }

  virtual ~AccumuloProxy_getTabletServers_result() throw();
  std::vector<std::string>  success;

  _AccumuloProxy_getTabletServers_result__isset __isset;

  void __set_success(const std::vector<std::string> & val);

  bool operator == (const AccumuloProxy_getTabletServers_result & rhs) const
  {
    if (!(success == rhs.success))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_getTabletServers_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_getTabletServers_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_getTabletServers_presult__isset {
  _AccumuloProxy_getTabletServers_presult__isset() : success(false) {}
  bool success :1;
} _AccumuloProxy_getTabletServers_presult__isset;

class AccumuloProxy_getTabletServers_presult {
 public:


  virtual ~AccumuloProxy_getTabletServers_presult() throw();
  std::vector<std::string> * success;

  _AccumuloProxy_getTabletServers_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_removeProperty_args__isset {
  _AccumuloProxy_removeProperty_args__isset() : login(false), property(false) {}
  bool login :1;
  bool property :1;
} _AccumuloProxy_removeProperty_args__isset;

class AccumuloProxy_removeProperty_args {
 public:

  AccumuloProxy_removeProperty_args(const AccumuloProxy_removeProperty_args&);
  AccumuloProxy_removeProperty_args& operator=(const AccumuloProxy_removeProperty_args&);
  AccumuloProxy_removeProperty_args() : login(), property() {
  }

  virtual ~AccumuloProxy_removeProperty_args() throw();
  std::string login;
  std::string property;

  _AccumuloProxy_removeProperty_args__isset __isset;

  void __set_login(const std::string& val);

  void __set_property(const std::string& val);

  bool operator == (const AccumuloProxy_removeProperty_args & rhs) const
  {
    if (!(login == rhs.login))
      return false;
    if (!(property == rhs.property))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_removeProperty_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_removeProperty_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_removeProperty_pargs {
 public:


  virtual ~AccumuloProxy_removeProperty_pargs() throw();
  const std::string* login;
  const std::string* property;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_removeProperty_result__isset {
  _AccumuloProxy_removeProperty_result__isset() : ouch1(false), ouch2(false) {}
  bool ouch1 :1;
  bool ouch2 :1;
} _AccumuloProxy_removeProperty_result__isset;

class AccumuloProxy_removeProperty_result {
 public:

  AccumuloProxy_removeProperty_result(const AccumuloProxy_removeProperty_result&);
  AccumuloProxy_removeProperty_result& operator=(const AccumuloProxy_removeProperty_result&);
  AccumuloProxy_removeProperty_result() {
  }

  virtual ~AccumuloProxy_removeProperty_result() throw();
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;

  _AccumuloProxy_removeProperty_result__isset __isset;

  void __set_ouch1(const AccumuloException& val);

  void __set_ouch2(const AccumuloSecurityException& val);

  bool operator == (const AccumuloProxy_removeProperty_result & rhs) const
  {
    if (!(ouch1 == rhs.ouch1))
      return false;
    if (!(ouch2 == rhs.ouch2))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_removeProperty_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_removeProperty_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_removeProperty_presult__isset {
  _AccumuloProxy_removeProperty_presult__isset() : ouch1(false), ouch2(false) {}
  bool ouch1 :1;
  bool ouch2 :1;
} _AccumuloProxy_removeProperty_presult__isset;

class AccumuloProxy_removeProperty_presult {
 public:


  virtual ~AccumuloProxy_removeProperty_presult() throw();
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;

  _AccumuloProxy_removeProperty_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_setProperty_args__isset {
  _AccumuloProxy_setProperty_args__isset() : login(false), property(false), value(false) {}
  bool login :1;
  bool property :1;
  bool value :1;
} _AccumuloProxy_setProperty_args__isset;

class AccumuloProxy_setProperty_args {
 public:

  AccumuloProxy_setProperty_args(const AccumuloProxy_setProperty_args&);
  AccumuloProxy_setProperty_args& operator=(const AccumuloProxy_setProperty_args&);
  AccumuloProxy_setProperty_args() : login(), property(), value() {
  }

  virtual ~AccumuloProxy_setProperty_args() throw();
  std::string login;
  std::string property;
  std::string value;

  _AccumuloProxy_setProperty_args__isset __isset;

  void __set_login(const std::string& val);

  void __set_property(const std::string& val);

  void __set_value(const std::string& val);

  bool operator == (const AccumuloProxy_setProperty_args & rhs) const
  {
    if (!(login == rhs.login))
      return false;
    if (!(property == rhs.property))
      return false;
    if (!(value == rhs.value))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_setProperty_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_setProperty_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_setProperty_pargs {
 public:


  virtual ~AccumuloProxy_setProperty_pargs() throw();
  const std::string* login;
  const std::string* property;
  const std::string* value;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_setProperty_result__isset {
  _AccumuloProxy_setProperty_result__isset() : ouch1(false), ouch2(false) {}
  bool ouch1 :1;
  bool ouch2 :1;
} _AccumuloProxy_setProperty_result__isset;

class AccumuloProxy_setProperty_result {
 public:

  AccumuloProxy_setProperty_result(const AccumuloProxy_setProperty_result&);
  AccumuloProxy_setProperty_result& operator=(const AccumuloProxy_setProperty_result&);
  AccumuloProxy_setProperty_result() {
  }

  virtual ~AccumuloProxy_setProperty_result() throw();
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;

  _AccumuloProxy_setProperty_result__isset __isset;

  void __set_ouch1(const AccumuloException& val);

  void __set_ouch2(const AccumuloSecurityException& val);

  bool operator == (const AccumuloProxy_setProperty_result & rhs) const
  {
    if (!(ouch1 == rhs.ouch1))
      return false;
    if (!(ouch2 == rhs.ouch2))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_setProperty_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_setProperty_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_setProperty_presult__isset {
  _AccumuloProxy_setProperty_presult__isset() : ouch1(false), ouch2(false) {}
  bool ouch1 :1;
  bool ouch2 :1;
} _AccumuloProxy_setProperty_presult__isset;

class AccumuloProxy_setProperty_presult {
 public:


  virtual ~AccumuloProxy_setProperty_presult() throw();
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;

  _AccumuloProxy_setProperty_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_testClassLoad_args__isset {
  _AccumuloProxy_testClassLoad_args__isset() : login(false), className(false), asTypeName(false) {}
  bool login :1;
  bool className :1;
  bool asTypeName :1;
} _AccumuloProxy_testClassLoad_args__isset;

class AccumuloProxy_testClassLoad_args {
 public:

  AccumuloProxy_testClassLoad_args(const AccumuloProxy_testClassLoad_args&);
  AccumuloProxy_testClassLoad_args& operator=(const AccumuloProxy_testClassLoad_args&);
  AccumuloProxy_testClassLoad_args() : login(), className(), asTypeName() {
  }

  virtual ~AccumuloProxy_testClassLoad_args() throw();
  std::string login;
  std::string className;
  std::string asTypeName;

  _AccumuloProxy_testClassLoad_args__isset __isset;

  void __set_login(const std::string& val);

  void __set_className(const std::string& val);

  void __set_asTypeName(const std::string& val);

  bool operator == (const AccumuloProxy_testClassLoad_args & rhs) const
  {
    if (!(login == rhs.login))
      return false;
    if (!(className == rhs.className))
      return false;
    if (!(asTypeName == rhs.asTypeName))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_testClassLoad_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_testClassLoad_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_testClassLoad_pargs {
 public:


  virtual ~AccumuloProxy_testClassLoad_pargs() throw();
  const std::string* login;
  const std::string* className;
  const std::string* asTypeName;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_testClassLoad_result__isset {
  _AccumuloProxy_testClassLoad_result__isset() : success(false), ouch1(false), ouch2(false) {}
  bool success :1;
  bool ouch1 :1;
  bool ouch2 :1;
} _AccumuloProxy_testClassLoad_result__isset;

class AccumuloProxy_testClassLoad_result {
 public:

  AccumuloProxy_testClassLoad_result(const AccumuloProxy_testClassLoad_result&);
  AccumuloProxy_testClassLoad_result& operator=(const AccumuloProxy_testClassLoad_result&);
  AccumuloProxy_testClassLoad_result() : success(0) {
  }

  virtual ~AccumuloProxy_testClassLoad_result() throw();
  bool success;
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;

  _AccumuloProxy_testClassLoad_result__isset __isset;

  void __set_success(const bool val);

  void __set_ouch1(const AccumuloException& val);

  void __set_ouch2(const AccumuloSecurityException& val);

  bool operator == (const AccumuloProxy_testClassLoad_result & rhs) const
  {
    if (!(success == rhs.success))
      return false;
    if (!(ouch1 == rhs.ouch1))
      return false;
    if (!(ouch2 == rhs.ouch2))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_testClassLoad_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_testClassLoad_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_testClassLoad_presult__isset {
  _AccumuloProxy_testClassLoad_presult__isset() : success(false), ouch1(false), ouch2(false) {}
  bool success :1;
  bool ouch1 :1;
  bool ouch2 :1;
} _AccumuloProxy_testClassLoad_presult__isset;

class AccumuloProxy_testClassLoad_presult {
 public:


  virtual ~AccumuloProxy_testClassLoad_presult() throw();
  bool* success;
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;

  _AccumuloProxy_testClassLoad_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_authenticateUser_args__isset {
  _AccumuloProxy_authenticateUser_args__isset() : login(false), user(false), properties(false) {}
  bool login :1;
  bool user :1;
  bool properties :1;
} _AccumuloProxy_authenticateUser_args__isset;

class AccumuloProxy_authenticateUser_args {
 public:

  AccumuloProxy_authenticateUser_args(const AccumuloProxy_authenticateUser_args&);
  AccumuloProxy_authenticateUser_args& operator=(const AccumuloProxy_authenticateUser_args&);
  AccumuloProxy_authenticateUser_args() : login(), user() {
  }

  virtual ~AccumuloProxy_authenticateUser_args() throw();
  std::string login;
  std::string user;
  std::map<std::string, std::string>  properties;

  _AccumuloProxy_authenticateUser_args__isset __isset;

  void __set_login(const std::string& val);

  void __set_user(const std::string& val);

  void __set_properties(const std::map<std::string, std::string> & val);

  bool operator == (const AccumuloProxy_authenticateUser_args & rhs) const
  {
    if (!(login == rhs.login))
      return false;
    if (!(user == rhs.user))
      return false;
    if (!(properties == rhs.properties))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_authenticateUser_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_authenticateUser_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_authenticateUser_pargs {
 public:


  virtual ~AccumuloProxy_authenticateUser_pargs() throw();
  const std::string* login;
  const std::string* user;
  const std::map<std::string, std::string> * properties;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_authenticateUser_result__isset {
  _AccumuloProxy_authenticateUser_result__isset() : success(false), ouch1(false), ouch2(false) {}
  bool success :1;
  bool ouch1 :1;
  bool ouch2 :1;
} _AccumuloProxy_authenticateUser_result__isset;

class AccumuloProxy_authenticateUser_result {
 public:

  AccumuloProxy_authenticateUser_result(const AccumuloProxy_authenticateUser_result&);
  AccumuloProxy_authenticateUser_result& operator=(const AccumuloProxy_authenticateUser_result&);
  AccumuloProxy_authenticateUser_result() : success(0) {
  }

  virtual ~AccumuloProxy_authenticateUser_result() throw();
  bool success;
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;

  _AccumuloProxy_authenticateUser_result__isset __isset;

  void __set_success(const bool val);

  void __set_ouch1(const AccumuloException& val);

  void __set_ouch2(const AccumuloSecurityException& val);

  bool operator == (const AccumuloProxy_authenticateUser_result & rhs) const
  {
    if (!(success == rhs.success))
      return false;
    if (!(ouch1 == rhs.ouch1))
      return false;
    if (!(ouch2 == rhs.ouch2))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_authenticateUser_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_authenticateUser_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_authenticateUser_presult__isset {
  _AccumuloProxy_authenticateUser_presult__isset() : success(false), ouch1(false), ouch2(false) {}
  bool success :1;
  bool ouch1 :1;
  bool ouch2 :1;
} _AccumuloProxy_authenticateUser_presult__isset;

class AccumuloProxy_authenticateUser_presult {
 public:


  virtual ~AccumuloProxy_authenticateUser_presult() throw();
  bool* success;
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;

  _AccumuloProxy_authenticateUser_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_changeUserAuthorizations_args__isset {
  _AccumuloProxy_changeUserAuthorizations_args__isset() : login(false), user(false), authorizations(false) {}
  bool login :1;
  bool user :1;
  bool authorizations :1;
} _AccumuloProxy_changeUserAuthorizations_args__isset;

class AccumuloProxy_changeUserAuthorizations_args {
 public:

  AccumuloProxy_changeUserAuthorizations_args(const AccumuloProxy_changeUserAuthorizations_args&);
  AccumuloProxy_changeUserAuthorizations_args& operator=(const AccumuloProxy_changeUserAuthorizations_args&);
  AccumuloProxy_changeUserAuthorizations_args() : login(), user() {
  }

  virtual ~AccumuloProxy_changeUserAuthorizations_args() throw();
  std::string login;
  std::string user;
  std::set<std::string>  authorizations;

  _AccumuloProxy_changeUserAuthorizations_args__isset __isset;

  void __set_login(const std::string& val);

  void __set_user(const std::string& val);

  void __set_authorizations(const std::set<std::string> & val);

  bool operator == (const AccumuloProxy_changeUserAuthorizations_args & rhs) const
  {
    if (!(login == rhs.login))
      return false;
    if (!(user == rhs.user))
      return false;
    if (!(authorizations == rhs.authorizations))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_changeUserAuthorizations_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_changeUserAuthorizations_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_changeUserAuthorizations_pargs {
 public:


  virtual ~AccumuloProxy_changeUserAuthorizations_pargs() throw();
  const std::string* login;
  const std::string* user;
  const std::set<std::string> * authorizations;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_changeUserAuthorizations_result__isset {
  _AccumuloProxy_changeUserAuthorizations_result__isset() : ouch1(false), ouch2(false) {}
  bool ouch1 :1;
  bool ouch2 :1;
} _AccumuloProxy_changeUserAuthorizations_result__isset;

class AccumuloProxy_changeUserAuthorizations_result {
 public:

  AccumuloProxy_changeUserAuthorizations_result(const AccumuloProxy_changeUserAuthorizations_result&);
  AccumuloProxy_changeUserAuthorizations_result& operator=(const AccumuloProxy_changeUserAuthorizations_result&);
  AccumuloProxy_changeUserAuthorizations_result() {
  }

  virtual ~AccumuloProxy_changeUserAuthorizations_result() throw();
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;

  _AccumuloProxy_changeUserAuthorizations_result__isset __isset;

  void __set_ouch1(const AccumuloException& val);

  void __set_ouch2(const AccumuloSecurityException& val);

  bool operator == (const AccumuloProxy_changeUserAuthorizations_result & rhs) const
  {
    if (!(ouch1 == rhs.ouch1))
      return false;
    if (!(ouch2 == rhs.ouch2))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_changeUserAuthorizations_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_changeUserAuthorizations_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_changeUserAuthorizations_presult__isset {
  _AccumuloProxy_changeUserAuthorizations_presult__isset() : ouch1(false), ouch2(false) {}
  bool ouch1 :1;
  bool ouch2 :1;
} _AccumuloProxy_changeUserAuthorizations_presult__isset;

class AccumuloProxy_changeUserAuthorizations_presult {
 public:


  virtual ~AccumuloProxy_changeUserAuthorizations_presult() throw();
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;

  _AccumuloProxy_changeUserAuthorizations_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_changeLocalUserPassword_args__isset {
  _AccumuloProxy_changeLocalUserPassword_args__isset() : login(false), user(false), password(false) {}
  bool login :1;
  bool user :1;
  bool password :1;
} _AccumuloProxy_changeLocalUserPassword_args__isset;

class AccumuloProxy_changeLocalUserPassword_args {
 public:

  AccumuloProxy_changeLocalUserPassword_args(const AccumuloProxy_changeLocalUserPassword_args&);
  AccumuloProxy_changeLocalUserPassword_args& operator=(const AccumuloProxy_changeLocalUserPassword_args&);
  AccumuloProxy_changeLocalUserPassword_args() : login(), user(), password() {
  }

  virtual ~AccumuloProxy_changeLocalUserPassword_args() throw();
  std::string login;
  std::string user;
  std::string password;

  _AccumuloProxy_changeLocalUserPassword_args__isset __isset;

  void __set_login(const std::string& val);

  void __set_user(const std::string& val);

  void __set_password(const std::string& val);

  bool operator == (const AccumuloProxy_changeLocalUserPassword_args & rhs) const
  {
    if (!(login == rhs.login))
      return false;
    if (!(user == rhs.user))
      return false;
    if (!(password == rhs.password))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_changeLocalUserPassword_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_changeLocalUserPassword_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_changeLocalUserPassword_pargs {
 public:


  virtual ~AccumuloProxy_changeLocalUserPassword_pargs() throw();
  const std::string* login;
  const std::string* user;
  const std::string* password;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_changeLocalUserPassword_result__isset {
  _AccumuloProxy_changeLocalUserPassword_result__isset() : ouch1(false), ouch2(false) {}
  bool ouch1 :1;
  bool ouch2 :1;
} _AccumuloProxy_changeLocalUserPassword_result__isset;

class AccumuloProxy_changeLocalUserPassword_result {
 public:

  AccumuloProxy_changeLocalUserPassword_result(const AccumuloProxy_changeLocalUserPassword_result&);
  AccumuloProxy_changeLocalUserPassword_result& operator=(const AccumuloProxy_changeLocalUserPassword_result&);
  AccumuloProxy_changeLocalUserPassword_result() {
  }

  virtual ~AccumuloProxy_changeLocalUserPassword_result() throw();
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;

  _AccumuloProxy_changeLocalUserPassword_result__isset __isset;

  void __set_ouch1(const AccumuloException& val);

  void __set_ouch2(const AccumuloSecurityException& val);

  bool operator == (const AccumuloProxy_changeLocalUserPassword_result & rhs) const
  {
    if (!(ouch1 == rhs.ouch1))
      return false;
    if (!(ouch2 == rhs.ouch2))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_changeLocalUserPassword_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_changeLocalUserPassword_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_changeLocalUserPassword_presult__isset {
  _AccumuloProxy_changeLocalUserPassword_presult__isset() : ouch1(false), ouch2(false) {}
  bool ouch1 :1;
  bool ouch2 :1;
} _AccumuloProxy_changeLocalUserPassword_presult__isset;

class AccumuloProxy_changeLocalUserPassword_presult {
 public:


  virtual ~AccumuloProxy_changeLocalUserPassword_presult() throw();
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;

  _AccumuloProxy_changeLocalUserPassword_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_createLocalUser_args__isset {
  _AccumuloProxy_createLocalUser_args__isset() : login(false), user(false), password(false) {}
  bool login :1;
  bool user :1;
  bool password :1;
} _AccumuloProxy_createLocalUser_args__isset;

class AccumuloProxy_createLocalUser_args {
 public:

  AccumuloProxy_createLocalUser_args(const AccumuloProxy_createLocalUser_args&);
  AccumuloProxy_createLocalUser_args& operator=(const AccumuloProxy_createLocalUser_args&);
  AccumuloProxy_createLocalUser_args() : login(), user(), password() {
  }

  virtual ~AccumuloProxy_createLocalUser_args() throw();
  std::string login;
  std::string user;
  std::string password;

  _AccumuloProxy_createLocalUser_args__isset __isset;

  void __set_login(const std::string& val);

  void __set_user(const std::string& val);

  void __set_password(const std::string& val);

  bool operator == (const AccumuloProxy_createLocalUser_args & rhs) const
  {
    if (!(login == rhs.login))
      return false;
    if (!(user == rhs.user))
      return false;
    if (!(password == rhs.password))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_createLocalUser_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_createLocalUser_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_createLocalUser_pargs {
 public:


  virtual ~AccumuloProxy_createLocalUser_pargs() throw();
  const std::string* login;
  const std::string* user;
  const std::string* password;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_createLocalUser_result__isset {
  _AccumuloProxy_createLocalUser_result__isset() : ouch1(false), ouch2(false) {}
  bool ouch1 :1;
  bool ouch2 :1;
} _AccumuloProxy_createLocalUser_result__isset;

class AccumuloProxy_createLocalUser_result {
 public:

  AccumuloProxy_createLocalUser_result(const AccumuloProxy_createLocalUser_result&);
  AccumuloProxy_createLocalUser_result& operator=(const AccumuloProxy_createLocalUser_result&);
  AccumuloProxy_createLocalUser_result() {
  }

  virtual ~AccumuloProxy_createLocalUser_result() throw();
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;

  _AccumuloProxy_createLocalUser_result__isset __isset;

  void __set_ouch1(const AccumuloException& val);

  void __set_ouch2(const AccumuloSecurityException& val);

  bool operator == (const AccumuloProxy_createLocalUser_result & rhs) const
  {
    if (!(ouch1 == rhs.ouch1))
      return false;
    if (!(ouch2 == rhs.ouch2))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_createLocalUser_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_createLocalUser_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_createLocalUser_presult__isset {
  _AccumuloProxy_createLocalUser_presult__isset() : ouch1(false), ouch2(false) {}
  bool ouch1 :1;
  bool ouch2 :1;
} _AccumuloProxy_createLocalUser_presult__isset;

class AccumuloProxy_createLocalUser_presult {
 public:


  virtual ~AccumuloProxy_createLocalUser_presult() throw();
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;

  _AccumuloProxy_createLocalUser_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_dropLocalUser_args__isset {
  _AccumuloProxy_dropLocalUser_args__isset() : login(false), user(false) {}
  bool login :1;
  bool user :1;
} _AccumuloProxy_dropLocalUser_args__isset;

class AccumuloProxy_dropLocalUser_args {
 public:

  AccumuloProxy_dropLocalUser_args(const AccumuloProxy_dropLocalUser_args&);
  AccumuloProxy_dropLocalUser_args& operator=(const AccumuloProxy_dropLocalUser_args&);
  AccumuloProxy_dropLocalUser_args() : login(), user() {
  }

  virtual ~AccumuloProxy_dropLocalUser_args() throw();
  std::string login;
  std::string user;

  _AccumuloProxy_dropLocalUser_args__isset __isset;

  void __set_login(const std::string& val);

  void __set_user(const std::string& val);

  bool operator == (const AccumuloProxy_dropLocalUser_args & rhs) const
  {
    if (!(login == rhs.login))
      return false;
    if (!(user == rhs.user))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_dropLocalUser_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_dropLocalUser_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_dropLocalUser_pargs {
 public:


  virtual ~AccumuloProxy_dropLocalUser_pargs() throw();
  const std::string* login;
  const std::string* user;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_dropLocalUser_result__isset {
  _AccumuloProxy_dropLocalUser_result__isset() : ouch1(false), ouch2(false) {}
  bool ouch1 :1;
  bool ouch2 :1;
} _AccumuloProxy_dropLocalUser_result__isset;

class AccumuloProxy_dropLocalUser_result {
 public:

  AccumuloProxy_dropLocalUser_result(const AccumuloProxy_dropLocalUser_result&);
  AccumuloProxy_dropLocalUser_result& operator=(const AccumuloProxy_dropLocalUser_result&);
  AccumuloProxy_dropLocalUser_result() {
  }

  virtual ~AccumuloProxy_dropLocalUser_result() throw();
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;

  _AccumuloProxy_dropLocalUser_result__isset __isset;

  void __set_ouch1(const AccumuloException& val);

  void __set_ouch2(const AccumuloSecurityException& val);

  bool operator == (const AccumuloProxy_dropLocalUser_result & rhs) const
  {
    if (!(ouch1 == rhs.ouch1))
      return false;
    if (!(ouch2 == rhs.ouch2))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_dropLocalUser_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_dropLocalUser_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_dropLocalUser_presult__isset {
  _AccumuloProxy_dropLocalUser_presult__isset() : ouch1(false), ouch2(false) {}
  bool ouch1 :1;
  bool ouch2 :1;
} _AccumuloProxy_dropLocalUser_presult__isset;

class AccumuloProxy_dropLocalUser_presult {
 public:


  virtual ~AccumuloProxy_dropLocalUser_presult() throw();
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;

  _AccumuloProxy_dropLocalUser_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_getUserAuthorizations_args__isset {
  _AccumuloProxy_getUserAuthorizations_args__isset() : login(false), user(false) {}
  bool login :1;
  bool user :1;
} _AccumuloProxy_getUserAuthorizations_args__isset;

class AccumuloProxy_getUserAuthorizations_args {
 public:

  AccumuloProxy_getUserAuthorizations_args(const AccumuloProxy_getUserAuthorizations_args&);
  AccumuloProxy_getUserAuthorizations_args& operator=(const AccumuloProxy_getUserAuthorizations_args&);
  AccumuloProxy_getUserAuthorizations_args() : login(), user() {
  }

  virtual ~AccumuloProxy_getUserAuthorizations_args() throw();
  std::string login;
  std::string user;

  _AccumuloProxy_getUserAuthorizations_args__isset __isset;

  void __set_login(const std::string& val);

  void __set_user(const std::string& val);

  bool operator == (const AccumuloProxy_getUserAuthorizations_args & rhs) const
  {
    if (!(login == rhs.login))
      return false;
    if (!(user == rhs.user))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_getUserAuthorizations_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_getUserAuthorizations_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_getUserAuthorizations_pargs {
 public:


  virtual ~AccumuloProxy_getUserAuthorizations_pargs() throw();
  const std::string* login;
  const std::string* user;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_getUserAuthorizations_result__isset {
  _AccumuloProxy_getUserAuthorizations_result__isset() : success(false), ouch1(false), ouch2(false) {}
  bool success :1;
  bool ouch1 :1;
  bool ouch2 :1;
} _AccumuloProxy_getUserAuthorizations_result__isset;

class AccumuloProxy_getUserAuthorizations_result {
 public:

  AccumuloProxy_getUserAuthorizations_result(const AccumuloProxy_getUserAuthorizations_result&);
  AccumuloProxy_getUserAuthorizations_result& operator=(const AccumuloProxy_getUserAuthorizations_result&);
  AccumuloProxy_getUserAuthorizations_result() {
  }

  virtual ~AccumuloProxy_getUserAuthorizations_result() throw();
  std::vector<std::string>  success;
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;

  _AccumuloProxy_getUserAuthorizations_result__isset __isset;

  void __set_success(const std::vector<std::string> & val);

  void __set_ouch1(const AccumuloException& val);

  void __set_ouch2(const AccumuloSecurityException& val);

  bool operator == (const AccumuloProxy_getUserAuthorizations_result & rhs) const
  {
    if (!(success == rhs.success))
      return false;
    if (!(ouch1 == rhs.ouch1))
      return false;
    if (!(ouch2 == rhs.ouch2))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_getUserAuthorizations_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_getUserAuthorizations_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_getUserAuthorizations_presult__isset {
  _AccumuloProxy_getUserAuthorizations_presult__isset() : success(false), ouch1(false), ouch2(false) {}
  bool success :1;
  bool ouch1 :1;
  bool ouch2 :1;
} _AccumuloProxy_getUserAuthorizations_presult__isset;

class AccumuloProxy_getUserAuthorizations_presult {
 public:


  virtual ~AccumuloProxy_getUserAuthorizations_presult() throw();
  std::vector<std::string> * success;
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;

  _AccumuloProxy_getUserAuthorizations_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_grantSystemPermission_args__isset {
  _AccumuloProxy_grantSystemPermission_args__isset() : login(false), user(false), perm(false) {}
  bool login :1;
  bool user :1;
  bool perm :1;
} _AccumuloProxy_grantSystemPermission_args__isset;

class AccumuloProxy_grantSystemPermission_args {
 public:

  AccumuloProxy_grantSystemPermission_args(const AccumuloProxy_grantSystemPermission_args&);
  AccumuloProxy_grantSystemPermission_args& operator=(const AccumuloProxy_grantSystemPermission_args&);
  AccumuloProxy_grantSystemPermission_args() : login(), user(), perm((SystemPermission::type)0) {
  }

  virtual ~AccumuloProxy_grantSystemPermission_args() throw();
  std::string login;
  std::string user;
  SystemPermission::type perm;

  _AccumuloProxy_grantSystemPermission_args__isset __isset;

  void __set_login(const std::string& val);

  void __set_user(const std::string& val);

  void __set_perm(const SystemPermission::type val);

  bool operator == (const AccumuloProxy_grantSystemPermission_args & rhs) const
  {
    if (!(login == rhs.login))
      return false;
    if (!(user == rhs.user))
      return false;
    if (!(perm == rhs.perm))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_grantSystemPermission_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_grantSystemPermission_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_grantSystemPermission_pargs {
 public:


  virtual ~AccumuloProxy_grantSystemPermission_pargs() throw();
  const std::string* login;
  const std::string* user;
  const SystemPermission::type* perm;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_grantSystemPermission_result__isset {
  _AccumuloProxy_grantSystemPermission_result__isset() : ouch1(false), ouch2(false) {}
  bool ouch1 :1;
  bool ouch2 :1;
} _AccumuloProxy_grantSystemPermission_result__isset;

class AccumuloProxy_grantSystemPermission_result {
 public:

  AccumuloProxy_grantSystemPermission_result(const AccumuloProxy_grantSystemPermission_result&);
  AccumuloProxy_grantSystemPermission_result& operator=(const AccumuloProxy_grantSystemPermission_result&);
  AccumuloProxy_grantSystemPermission_result() {
  }

  virtual ~AccumuloProxy_grantSystemPermission_result() throw();
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;

  _AccumuloProxy_grantSystemPermission_result__isset __isset;

  void __set_ouch1(const AccumuloException& val);

  void __set_ouch2(const AccumuloSecurityException& val);

  bool operator == (const AccumuloProxy_grantSystemPermission_result & rhs) const
  {
    if (!(ouch1 == rhs.ouch1))
      return false;
    if (!(ouch2 == rhs.ouch2))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_grantSystemPermission_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_grantSystemPermission_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_grantSystemPermission_presult__isset {
  _AccumuloProxy_grantSystemPermission_presult__isset() : ouch1(false), ouch2(false) {}
  bool ouch1 :1;
  bool ouch2 :1;
} _AccumuloProxy_grantSystemPermission_presult__isset;

class AccumuloProxy_grantSystemPermission_presult {
 public:


  virtual ~AccumuloProxy_grantSystemPermission_presult() throw();
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;

  _AccumuloProxy_grantSystemPermission_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_grantTablePermission_args__isset {
  _AccumuloProxy_grantTablePermission_args__isset() : login(false), user(false), table(false), perm(false) {}
  bool login :1;
  bool user :1;
  bool table :1;
  bool perm :1;
} _AccumuloProxy_grantTablePermission_args__isset;

class AccumuloProxy_grantTablePermission_args {
 public:

  AccumuloProxy_grantTablePermission_args(const AccumuloProxy_grantTablePermission_args&);
  AccumuloProxy_grantTablePermission_args& operator=(const AccumuloProxy_grantTablePermission_args&);
  AccumuloProxy_grantTablePermission_args() : login(), user(), table(), perm((TablePermission::type)0) {
  }

  virtual ~AccumuloProxy_grantTablePermission_args() throw();
  std::string login;
  std::string user;
  std::string table;
  TablePermission::type perm;

  _AccumuloProxy_grantTablePermission_args__isset __isset;

  void __set_login(const std::string& val);

  void __set_user(const std::string& val);

  void __set_table(const std::string& val);

  void __set_perm(const TablePermission::type val);

  bool operator == (const AccumuloProxy_grantTablePermission_args & rhs) const
  {
    if (!(login == rhs.login))
      return false;
    if (!(user == rhs.user))
      return false;
    if (!(table == rhs.table))
      return false;
    if (!(perm == rhs.perm))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_grantTablePermission_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_grantTablePermission_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_grantTablePermission_pargs {
 public:


  virtual ~AccumuloProxy_grantTablePermission_pargs() throw();
  const std::string* login;
  const std::string* user;
  const std::string* table;
  const TablePermission::type* perm;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_grantTablePermission_result__isset {
  _AccumuloProxy_grantTablePermission_result__isset() : ouch1(false), ouch2(false), ouch3(false) {}
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_grantTablePermission_result__isset;

class AccumuloProxy_grantTablePermission_result {
 public:

  AccumuloProxy_grantTablePermission_result(const AccumuloProxy_grantTablePermission_result&);
  AccumuloProxy_grantTablePermission_result& operator=(const AccumuloProxy_grantTablePermission_result&);
  AccumuloProxy_grantTablePermission_result() {
  }

  virtual ~AccumuloProxy_grantTablePermission_result() throw();
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  TableNotFoundException ouch3;

  _AccumuloProxy_grantTablePermission_result__isset __isset;

  void __set_ouch1(const AccumuloException& val);

  void __set_ouch2(const AccumuloSecurityException& val);

  void __set_ouch3(const TableNotFoundException& val);

  bool operator == (const AccumuloProxy_grantTablePermission_result & rhs) const
  {
    if (!(ouch1 == rhs.ouch1))
      return false;
    if (!(ouch2 == rhs.ouch2))
      return false;
    if (!(ouch3 == rhs.ouch3))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_grantTablePermission_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_grantTablePermission_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_grantTablePermission_presult__isset {
  _AccumuloProxy_grantTablePermission_presult__isset() : ouch1(false), ouch2(false), ouch3(false) {}
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_grantTablePermission_presult__isset;

class AccumuloProxy_grantTablePermission_presult {
 public:


  virtual ~AccumuloProxy_grantTablePermission_presult() throw();
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  TableNotFoundException ouch3;

  _AccumuloProxy_grantTablePermission_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_hasSystemPermission_args__isset {
  _AccumuloProxy_hasSystemPermission_args__isset() : login(false), user(false), perm(false) {}
  bool login :1;
  bool user :1;
  bool perm :1;
} _AccumuloProxy_hasSystemPermission_args__isset;

class AccumuloProxy_hasSystemPermission_args {
 public:

  AccumuloProxy_hasSystemPermission_args(const AccumuloProxy_hasSystemPermission_args&);
  AccumuloProxy_hasSystemPermission_args& operator=(const AccumuloProxy_hasSystemPermission_args&);
  AccumuloProxy_hasSystemPermission_args() : login(), user(), perm((SystemPermission::type)0) {
  }

  virtual ~AccumuloProxy_hasSystemPermission_args() throw();
  std::string login;
  std::string user;
  SystemPermission::type perm;

  _AccumuloProxy_hasSystemPermission_args__isset __isset;

  void __set_login(const std::string& val);

  void __set_user(const std::string& val);

  void __set_perm(const SystemPermission::type val);

  bool operator == (const AccumuloProxy_hasSystemPermission_args & rhs) const
  {
    if (!(login == rhs.login))
      return false;
    if (!(user == rhs.user))
      return false;
    if (!(perm == rhs.perm))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_hasSystemPermission_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_hasSystemPermission_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_hasSystemPermission_pargs {
 public:


  virtual ~AccumuloProxy_hasSystemPermission_pargs() throw();
  const std::string* login;
  const std::string* user;
  const SystemPermission::type* perm;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_hasSystemPermission_result__isset {
  _AccumuloProxy_hasSystemPermission_result__isset() : success(false), ouch1(false), ouch2(false) {}
  bool success :1;
  bool ouch1 :1;
  bool ouch2 :1;
} _AccumuloProxy_hasSystemPermission_result__isset;

class AccumuloProxy_hasSystemPermission_result {
 public:

  AccumuloProxy_hasSystemPermission_result(const AccumuloProxy_hasSystemPermission_result&);
  AccumuloProxy_hasSystemPermission_result& operator=(const AccumuloProxy_hasSystemPermission_result&);
  AccumuloProxy_hasSystemPermission_result() : success(0) {
  }

  virtual ~AccumuloProxy_hasSystemPermission_result() throw();
  bool success;
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;

  _AccumuloProxy_hasSystemPermission_result__isset __isset;

  void __set_success(const bool val);

  void __set_ouch1(const AccumuloException& val);

  void __set_ouch2(const AccumuloSecurityException& val);

  bool operator == (const AccumuloProxy_hasSystemPermission_result & rhs) const
  {
    if (!(success == rhs.success))
      return false;
    if (!(ouch1 == rhs.ouch1))
      return false;
    if (!(ouch2 == rhs.ouch2))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_hasSystemPermission_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_hasSystemPermission_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_hasSystemPermission_presult__isset {
  _AccumuloProxy_hasSystemPermission_presult__isset() : success(false), ouch1(false), ouch2(false) {}
  bool success :1;
  bool ouch1 :1;
  bool ouch2 :1;
} _AccumuloProxy_hasSystemPermission_presult__isset;

class AccumuloProxy_hasSystemPermission_presult {
 public:


  virtual ~AccumuloProxy_hasSystemPermission_presult() throw();
  bool* success;
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;

  _AccumuloProxy_hasSystemPermission_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_hasTablePermission_args__isset {
  _AccumuloProxy_hasTablePermission_args__isset() : login(false), user(false), table(false), perm(false) {}
  bool login :1;
  bool user :1;
  bool table :1;
  bool perm :1;
} _AccumuloProxy_hasTablePermission_args__isset;

class AccumuloProxy_hasTablePermission_args {
 public:

  AccumuloProxy_hasTablePermission_args(const AccumuloProxy_hasTablePermission_args&);
  AccumuloProxy_hasTablePermission_args& operator=(const AccumuloProxy_hasTablePermission_args&);
  AccumuloProxy_hasTablePermission_args() : login(), user(), table(), perm((TablePermission::type)0) {
  }

  virtual ~AccumuloProxy_hasTablePermission_args() throw();
  std::string login;
  std::string user;
  std::string table;
  TablePermission::type perm;

  _AccumuloProxy_hasTablePermission_args__isset __isset;

  void __set_login(const std::string& val);

  void __set_user(const std::string& val);

  void __set_table(const std::string& val);

  void __set_perm(const TablePermission::type val);

  bool operator == (const AccumuloProxy_hasTablePermission_args & rhs) const
  {
    if (!(login == rhs.login))
      return false;
    if (!(user == rhs.user))
      return false;
    if (!(table == rhs.table))
      return false;
    if (!(perm == rhs.perm))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_hasTablePermission_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_hasTablePermission_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_hasTablePermission_pargs {
 public:


  virtual ~AccumuloProxy_hasTablePermission_pargs() throw();
  const std::string* login;
  const std::string* user;
  const std::string* table;
  const TablePermission::type* perm;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_hasTablePermission_result__isset {
  _AccumuloProxy_hasTablePermission_result__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
  bool success :1;
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_hasTablePermission_result__isset;

class AccumuloProxy_hasTablePermission_result {
 public:

  AccumuloProxy_hasTablePermission_result(const AccumuloProxy_hasTablePermission_result&);
  AccumuloProxy_hasTablePermission_result& operator=(const AccumuloProxy_hasTablePermission_result&);
  AccumuloProxy_hasTablePermission_result() : success(0) {
  }

  virtual ~AccumuloProxy_hasTablePermission_result() throw();
  bool success;
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  TableNotFoundException ouch3;

  _AccumuloProxy_hasTablePermission_result__isset __isset;

  void __set_success(const bool val);

  void __set_ouch1(const AccumuloException& val);

  void __set_ouch2(const AccumuloSecurityException& val);

  void __set_ouch3(const TableNotFoundException& val);

  bool operator == (const AccumuloProxy_hasTablePermission_result & rhs) const
  {
    if (!(success == rhs.success))
      return false;
    if (!(ouch1 == rhs.ouch1))
      return false;
    if (!(ouch2 == rhs.ouch2))
      return false;
    if (!(ouch3 == rhs.ouch3))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_hasTablePermission_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_hasTablePermission_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_hasTablePermission_presult__isset {
  _AccumuloProxy_hasTablePermission_presult__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
  bool success :1;
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_hasTablePermission_presult__isset;

class AccumuloProxy_hasTablePermission_presult {
 public:


  virtual ~AccumuloProxy_hasTablePermission_presult() throw();
  bool* success;
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  TableNotFoundException ouch3;

  _AccumuloProxy_hasTablePermission_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_listLocalUsers_args__isset {
  _AccumuloProxy_listLocalUsers_args__isset() : login(false) {}
  bool login :1;
} _AccumuloProxy_listLocalUsers_args__isset;

class AccumuloProxy_listLocalUsers_args {
 public:

  AccumuloProxy_listLocalUsers_args(const AccumuloProxy_listLocalUsers_args&);
  AccumuloProxy_listLocalUsers_args& operator=(const AccumuloProxy_listLocalUsers_args&);
  AccumuloProxy_listLocalUsers_args() : login() {
  }

  virtual ~AccumuloProxy_listLocalUsers_args() throw();
  std::string login;

  _AccumuloProxy_listLocalUsers_args__isset __isset;

  void __set_login(const std::string& val);

  bool operator == (const AccumuloProxy_listLocalUsers_args & rhs) const
  {
    if (!(login == rhs.login))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_listLocalUsers_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_listLocalUsers_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_listLocalUsers_pargs {
 public:


  virtual ~AccumuloProxy_listLocalUsers_pargs() throw();
  const std::string* login;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_listLocalUsers_result__isset {
  _AccumuloProxy_listLocalUsers_result__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
  bool success :1;
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_listLocalUsers_result__isset;

class AccumuloProxy_listLocalUsers_result {
 public:

  AccumuloProxy_listLocalUsers_result(const AccumuloProxy_listLocalUsers_result&);
  AccumuloProxy_listLocalUsers_result& operator=(const AccumuloProxy_listLocalUsers_result&);
  AccumuloProxy_listLocalUsers_result() {
  }

  virtual ~AccumuloProxy_listLocalUsers_result() throw();
  std::set<std::string>  success;
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  TableNotFoundException ouch3;

  _AccumuloProxy_listLocalUsers_result__isset __isset;

  void __set_success(const std::set<std::string> & val);

  void __set_ouch1(const AccumuloException& val);

  void __set_ouch2(const AccumuloSecurityException& val);

  void __set_ouch3(const TableNotFoundException& val);

  bool operator == (const AccumuloProxy_listLocalUsers_result & rhs) const
  {
    if (!(success == rhs.success))
      return false;
    if (!(ouch1 == rhs.ouch1))
      return false;
    if (!(ouch2 == rhs.ouch2))
      return false;
    if (!(ouch3 == rhs.ouch3))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_listLocalUsers_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_listLocalUsers_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_listLocalUsers_presult__isset {
  _AccumuloProxy_listLocalUsers_presult__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
  bool success :1;
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_listLocalUsers_presult__isset;

class AccumuloProxy_listLocalUsers_presult {
 public:


  virtual ~AccumuloProxy_listLocalUsers_presult() throw();
  std::set<std::string> * success;
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  TableNotFoundException ouch3;

  _AccumuloProxy_listLocalUsers_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_revokeSystemPermission_args__isset {
  _AccumuloProxy_revokeSystemPermission_args__isset() : login(false), user(false), perm(false) {}
  bool login :1;
  bool user :1;
  bool perm :1;
} _AccumuloProxy_revokeSystemPermission_args__isset;

class AccumuloProxy_revokeSystemPermission_args {
 public:

  AccumuloProxy_revokeSystemPermission_args(const AccumuloProxy_revokeSystemPermission_args&);
  AccumuloProxy_revokeSystemPermission_args& operator=(const AccumuloProxy_revokeSystemPermission_args&);
  AccumuloProxy_revokeSystemPermission_args() : login(), user(), perm((SystemPermission::type)0) {
  }

  virtual ~AccumuloProxy_revokeSystemPermission_args() throw();
  std::string login;
  std::string user;
  SystemPermission::type perm;

  _AccumuloProxy_revokeSystemPermission_args__isset __isset;

  void __set_login(const std::string& val);

  void __set_user(const std::string& val);

  void __set_perm(const SystemPermission::type val);

  bool operator == (const AccumuloProxy_revokeSystemPermission_args & rhs) const
  {
    if (!(login == rhs.login))
      return false;
    if (!(user == rhs.user))
      return false;
    if (!(perm == rhs.perm))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_revokeSystemPermission_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_revokeSystemPermission_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_revokeSystemPermission_pargs {
 public:


  virtual ~AccumuloProxy_revokeSystemPermission_pargs() throw();
  const std::string* login;
  const std::string* user;
  const SystemPermission::type* perm;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_revokeSystemPermission_result__isset {
  _AccumuloProxy_revokeSystemPermission_result__isset() : ouch1(false), ouch2(false) {}
  bool ouch1 :1;
  bool ouch2 :1;
} _AccumuloProxy_revokeSystemPermission_result__isset;

class AccumuloProxy_revokeSystemPermission_result {
 public:

  AccumuloProxy_revokeSystemPermission_result(const AccumuloProxy_revokeSystemPermission_result&);
  AccumuloProxy_revokeSystemPermission_result& operator=(const AccumuloProxy_revokeSystemPermission_result&);
  AccumuloProxy_revokeSystemPermission_result() {
  }

  virtual ~AccumuloProxy_revokeSystemPermission_result() throw();
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;

  _AccumuloProxy_revokeSystemPermission_result__isset __isset;

  void __set_ouch1(const AccumuloException& val);

  void __set_ouch2(const AccumuloSecurityException& val);

  bool operator == (const AccumuloProxy_revokeSystemPermission_result & rhs) const
  {
    if (!(ouch1 == rhs.ouch1))
      return false;
    if (!(ouch2 == rhs.ouch2))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_revokeSystemPermission_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_revokeSystemPermission_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_revokeSystemPermission_presult__isset {
  _AccumuloProxy_revokeSystemPermission_presult__isset() : ouch1(false), ouch2(false) {}
  bool ouch1 :1;
  bool ouch2 :1;
} _AccumuloProxy_revokeSystemPermission_presult__isset;

class AccumuloProxy_revokeSystemPermission_presult {
 public:


  virtual ~AccumuloProxy_revokeSystemPermission_presult() throw();
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;

  _AccumuloProxy_revokeSystemPermission_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_revokeTablePermission_args__isset {
  _AccumuloProxy_revokeTablePermission_args__isset() : login(false), user(false), table(false), perm(false) {}
  bool login :1;
  bool user :1;
  bool table :1;
  bool perm :1;
} _AccumuloProxy_revokeTablePermission_args__isset;

class AccumuloProxy_revokeTablePermission_args {
 public:

  AccumuloProxy_revokeTablePermission_args(const AccumuloProxy_revokeTablePermission_args&);
  AccumuloProxy_revokeTablePermission_args& operator=(const AccumuloProxy_revokeTablePermission_args&);
  AccumuloProxy_revokeTablePermission_args() : login(), user(), table(), perm((TablePermission::type)0) {
  }

  virtual ~AccumuloProxy_revokeTablePermission_args() throw();
  std::string login;
  std::string user;
  std::string table;
  TablePermission::type perm;

  _AccumuloProxy_revokeTablePermission_args__isset __isset;

  void __set_login(const std::string& val);

  void __set_user(const std::string& val);

  void __set_table(const std::string& val);

  void __set_perm(const TablePermission::type val);

  bool operator == (const AccumuloProxy_revokeTablePermission_args & rhs) const
  {
    if (!(login == rhs.login))
      return false;
    if (!(user == rhs.user))
      return false;
    if (!(table == rhs.table))
      return false;
    if (!(perm == rhs.perm))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_revokeTablePermission_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_revokeTablePermission_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_revokeTablePermission_pargs {
 public:


  virtual ~AccumuloProxy_revokeTablePermission_pargs() throw();
  const std::string* login;
  const std::string* user;
  const std::string* table;
  const TablePermission::type* perm;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_revokeTablePermission_result__isset {
  _AccumuloProxy_revokeTablePermission_result__isset() : ouch1(false), ouch2(false), ouch3(false) {}
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_revokeTablePermission_result__isset;

class AccumuloProxy_revokeTablePermission_result {
 public:

  AccumuloProxy_revokeTablePermission_result(const AccumuloProxy_revokeTablePermission_result&);
  AccumuloProxy_revokeTablePermission_result& operator=(const AccumuloProxy_revokeTablePermission_result&);
  AccumuloProxy_revokeTablePermission_result() {
  }

  virtual ~AccumuloProxy_revokeTablePermission_result() throw();
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  TableNotFoundException ouch3;

  _AccumuloProxy_revokeTablePermission_result__isset __isset;

  void __set_ouch1(const AccumuloException& val);

  void __set_ouch2(const AccumuloSecurityException& val);

  void __set_ouch3(const TableNotFoundException& val);

  bool operator == (const AccumuloProxy_revokeTablePermission_result & rhs) const
  {
    if (!(ouch1 == rhs.ouch1))
      return false;
    if (!(ouch2 == rhs.ouch2))
      return false;
    if (!(ouch3 == rhs.ouch3))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_revokeTablePermission_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_revokeTablePermission_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_revokeTablePermission_presult__isset {
  _AccumuloProxy_revokeTablePermission_presult__isset() : ouch1(false), ouch2(false), ouch3(false) {}
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_revokeTablePermission_presult__isset;

class AccumuloProxy_revokeTablePermission_presult {
 public:


  virtual ~AccumuloProxy_revokeTablePermission_presult() throw();
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  TableNotFoundException ouch3;

  _AccumuloProxy_revokeTablePermission_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_grantNamespacePermission_args__isset {
  _AccumuloProxy_grantNamespacePermission_args__isset() : login(false), user(false), namespaceName(false), perm(false) {}
  bool login :1;
  bool user :1;
  bool namespaceName :1;
  bool perm :1;
} _AccumuloProxy_grantNamespacePermission_args__isset;

class AccumuloProxy_grantNamespacePermission_args {
 public:

  AccumuloProxy_grantNamespacePermission_args(const AccumuloProxy_grantNamespacePermission_args&);
  AccumuloProxy_grantNamespacePermission_args& operator=(const AccumuloProxy_grantNamespacePermission_args&);
  AccumuloProxy_grantNamespacePermission_args() : login(), user(), namespaceName(), perm((NamespacePermission::type)0) {
  }

  virtual ~AccumuloProxy_grantNamespacePermission_args() throw();
  std::string login;
  std::string user;
  std::string namespaceName;
  NamespacePermission::type perm;

  _AccumuloProxy_grantNamespacePermission_args__isset __isset;

  void __set_login(const std::string& val);

  void __set_user(const std::string& val);

  void __set_namespaceName(const std::string& val);

  void __set_perm(const NamespacePermission::type val);

  bool operator == (const AccumuloProxy_grantNamespacePermission_args & rhs) const
  {
    if (!(login == rhs.login))
      return false;
    if (!(user == rhs.user))
      return false;
    if (!(namespaceName == rhs.namespaceName))
      return false;
    if (!(perm == rhs.perm))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_grantNamespacePermission_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_grantNamespacePermission_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_grantNamespacePermission_pargs {
 public:


  virtual ~AccumuloProxy_grantNamespacePermission_pargs() throw();
  const std::string* login;
  const std::string* user;
  const std::string* namespaceName;
  const NamespacePermission::type* perm;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_grantNamespacePermission_result__isset {
  _AccumuloProxy_grantNamespacePermission_result__isset() : ouch1(false), ouch2(false) {}
  bool ouch1 :1;
  bool ouch2 :1;
} _AccumuloProxy_grantNamespacePermission_result__isset;

class AccumuloProxy_grantNamespacePermission_result {
 public:

  AccumuloProxy_grantNamespacePermission_result(const AccumuloProxy_grantNamespacePermission_result&);
  AccumuloProxy_grantNamespacePermission_result& operator=(const AccumuloProxy_grantNamespacePermission_result&);
  AccumuloProxy_grantNamespacePermission_result() {
  }

  virtual ~AccumuloProxy_grantNamespacePermission_result() throw();
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;

  _AccumuloProxy_grantNamespacePermission_result__isset __isset;

  void __set_ouch1(const AccumuloException& val);

  void __set_ouch2(const AccumuloSecurityException& val);

  bool operator == (const AccumuloProxy_grantNamespacePermission_result & rhs) const
  {
    if (!(ouch1 == rhs.ouch1))
      return false;
    if (!(ouch2 == rhs.ouch2))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_grantNamespacePermission_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_grantNamespacePermission_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_grantNamespacePermission_presult__isset {
  _AccumuloProxy_grantNamespacePermission_presult__isset() : ouch1(false), ouch2(false) {}
  bool ouch1 :1;
  bool ouch2 :1;
} _AccumuloProxy_grantNamespacePermission_presult__isset;

class AccumuloProxy_grantNamespacePermission_presult {
 public:


  virtual ~AccumuloProxy_grantNamespacePermission_presult() throw();
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;

  _AccumuloProxy_grantNamespacePermission_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_hasNamespacePermission_args__isset {
  _AccumuloProxy_hasNamespacePermission_args__isset() : login(false), user(false), namespaceName(false), perm(false) {}
  bool login :1;
  bool user :1;
  bool namespaceName :1;
  bool perm :1;
} _AccumuloProxy_hasNamespacePermission_args__isset;

class AccumuloProxy_hasNamespacePermission_args {
 public:

  AccumuloProxy_hasNamespacePermission_args(const AccumuloProxy_hasNamespacePermission_args&);
  AccumuloProxy_hasNamespacePermission_args& operator=(const AccumuloProxy_hasNamespacePermission_args&);
  AccumuloProxy_hasNamespacePermission_args() : login(), user(), namespaceName(), perm((NamespacePermission::type)0) {
  }

  virtual ~AccumuloProxy_hasNamespacePermission_args() throw();
  std::string login;
  std::string user;
  std::string namespaceName;
  NamespacePermission::type perm;

  _AccumuloProxy_hasNamespacePermission_args__isset __isset;

  void __set_login(const std::string& val);

  void __set_user(const std::string& val);

  void __set_namespaceName(const std::string& val);

  void __set_perm(const NamespacePermission::type val);

  bool operator == (const AccumuloProxy_hasNamespacePermission_args & rhs) const
  {
    if (!(login == rhs.login))
      return false;
    if (!(user == rhs.user))
      return false;
    if (!(namespaceName == rhs.namespaceName))
      return false;
    if (!(perm == rhs.perm))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_hasNamespacePermission_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_hasNamespacePermission_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_hasNamespacePermission_pargs {
 public:


  virtual ~AccumuloProxy_hasNamespacePermission_pargs() throw();
  const std::string* login;
  const std::string* user;
  const std::string* namespaceName;
  const NamespacePermission::type* perm;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_hasNamespacePermission_result__isset {
  _AccumuloProxy_hasNamespacePermission_result__isset() : success(false), ouch1(false), ouch2(false) {}
  bool success :1;
  bool ouch1 :1;
  bool ouch2 :1;
} _AccumuloProxy_hasNamespacePermission_result__isset;

class AccumuloProxy_hasNamespacePermission_result {
 public:

  AccumuloProxy_hasNamespacePermission_result(const AccumuloProxy_hasNamespacePermission_result&);
  AccumuloProxy_hasNamespacePermission_result& operator=(const AccumuloProxy_hasNamespacePermission_result&);
  AccumuloProxy_hasNamespacePermission_result() : success(0) {
  }

  virtual ~AccumuloProxy_hasNamespacePermission_result() throw();
  bool success;
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;

  _AccumuloProxy_hasNamespacePermission_result__isset __isset;

  void __set_success(const bool val);

  void __set_ouch1(const AccumuloException& val);

  void __set_ouch2(const AccumuloSecurityException& val);

  bool operator == (const AccumuloProxy_hasNamespacePermission_result & rhs) const
  {
    if (!(success == rhs.success))
      return false;
    if (!(ouch1 == rhs.ouch1))
      return false;
    if (!(ouch2 == rhs.ouch2))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_hasNamespacePermission_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_hasNamespacePermission_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_hasNamespacePermission_presult__isset {
  _AccumuloProxy_hasNamespacePermission_presult__isset() : success(false), ouch1(false), ouch2(false) {}
  bool success :1;
  bool ouch1 :1;
  bool ouch2 :1;
} _AccumuloProxy_hasNamespacePermission_presult__isset;

class AccumuloProxy_hasNamespacePermission_presult {
 public:


  virtual ~AccumuloProxy_hasNamespacePermission_presult() throw();
  bool* success;
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;

  _AccumuloProxy_hasNamespacePermission_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_revokeNamespacePermission_args__isset {
  _AccumuloProxy_revokeNamespacePermission_args__isset() : login(false), user(false), namespaceName(false), perm(false) {}
  bool login :1;
  bool user :1;
  bool namespaceName :1;
  bool perm :1;
} _AccumuloProxy_revokeNamespacePermission_args__isset;

class AccumuloProxy_revokeNamespacePermission_args {
 public:

  AccumuloProxy_revokeNamespacePermission_args(const AccumuloProxy_revokeNamespacePermission_args&);
  AccumuloProxy_revokeNamespacePermission_args& operator=(const AccumuloProxy_revokeNamespacePermission_args&);
  AccumuloProxy_revokeNamespacePermission_args() : login(), user(), namespaceName(), perm((NamespacePermission::type)0) {
  }

  virtual ~AccumuloProxy_revokeNamespacePermission_args() throw();
  std::string login;
  std::string user;
  std::string namespaceName;
  NamespacePermission::type perm;

  _AccumuloProxy_revokeNamespacePermission_args__isset __isset;

  void __set_login(const std::string& val);

  void __set_user(const std::string& val);

  void __set_namespaceName(const std::string& val);

  void __set_perm(const NamespacePermission::type val);

  bool operator == (const AccumuloProxy_revokeNamespacePermission_args & rhs) const
  {
    if (!(login == rhs.login))
      return false;
    if (!(user == rhs.user))
      return false;
    if (!(namespaceName == rhs.namespaceName))
      return false;
    if (!(perm == rhs.perm))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_revokeNamespacePermission_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_revokeNamespacePermission_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_revokeNamespacePermission_pargs {
 public:


  virtual ~AccumuloProxy_revokeNamespacePermission_pargs() throw();
  const std::string* login;
  const std::string* user;
  const std::string* namespaceName;
  const NamespacePermission::type* perm;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_revokeNamespacePermission_result__isset {
  _AccumuloProxy_revokeNamespacePermission_result__isset() : ouch1(false), ouch2(false) {}
  bool ouch1 :1;
  bool ouch2 :1;
} _AccumuloProxy_revokeNamespacePermission_result__isset;

class AccumuloProxy_revokeNamespacePermission_result {
 public:

  AccumuloProxy_revokeNamespacePermission_result(const AccumuloProxy_revokeNamespacePermission_result&);
  AccumuloProxy_revokeNamespacePermission_result& operator=(const AccumuloProxy_revokeNamespacePermission_result&);
  AccumuloProxy_revokeNamespacePermission_result() {
  }

  virtual ~AccumuloProxy_revokeNamespacePermission_result() throw();
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;

  _AccumuloProxy_revokeNamespacePermission_result__isset __isset;

  void __set_ouch1(const AccumuloException& val);

  void __set_ouch2(const AccumuloSecurityException& val);

  bool operator == (const AccumuloProxy_revokeNamespacePermission_result & rhs) const
  {
    if (!(ouch1 == rhs.ouch1))
      return false;
    if (!(ouch2 == rhs.ouch2))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_revokeNamespacePermission_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_revokeNamespacePermission_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_revokeNamespacePermission_presult__isset {
  _AccumuloProxy_revokeNamespacePermission_presult__isset() : ouch1(false), ouch2(false) {}
  bool ouch1 :1;
  bool ouch2 :1;
} _AccumuloProxy_revokeNamespacePermission_presult__isset;

class AccumuloProxy_revokeNamespacePermission_presult {
 public:


  virtual ~AccumuloProxy_revokeNamespacePermission_presult() throw();
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;

  _AccumuloProxy_revokeNamespacePermission_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_createBatchScanner_args__isset {
  _AccumuloProxy_createBatchScanner_args__isset() : login(false), tableName(false), options(false) {}
  bool login :1;
  bool tableName :1;
  bool options :1;
} _AccumuloProxy_createBatchScanner_args__isset;

class AccumuloProxy_createBatchScanner_args {
 public:

  AccumuloProxy_createBatchScanner_args(const AccumuloProxy_createBatchScanner_args&);
  AccumuloProxy_createBatchScanner_args& operator=(const AccumuloProxy_createBatchScanner_args&);
  AccumuloProxy_createBatchScanner_args() : login(), tableName() {
  }

  virtual ~AccumuloProxy_createBatchScanner_args() throw();
  std::string login;
  std::string tableName;
  BatchScanOptions options;

  _AccumuloProxy_createBatchScanner_args__isset __isset;

  void __set_login(const std::string& val);

  void __set_tableName(const std::string& val);

  void __set_options(const BatchScanOptions& val);

  bool operator == (const AccumuloProxy_createBatchScanner_args & rhs) const
  {
    if (!(login == rhs.login))
      return false;
    if (!(tableName == rhs.tableName))
      return false;
    if (!(options == rhs.options))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_createBatchScanner_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_createBatchScanner_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_createBatchScanner_pargs {
 public:


  virtual ~AccumuloProxy_createBatchScanner_pargs() throw();
  const std::string* login;
  const std::string* tableName;
  const BatchScanOptions* options;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_createBatchScanner_result__isset {
  _AccumuloProxy_createBatchScanner_result__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
  bool success :1;
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_createBatchScanner_result__isset;

class AccumuloProxy_createBatchScanner_result {
 public:

  AccumuloProxy_createBatchScanner_result(const AccumuloProxy_createBatchScanner_result&);
  AccumuloProxy_createBatchScanner_result& operator=(const AccumuloProxy_createBatchScanner_result&);
  AccumuloProxy_createBatchScanner_result() : success() {
  }

  virtual ~AccumuloProxy_createBatchScanner_result() throw();
  std::string success;
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  TableNotFoundException ouch3;

  _AccumuloProxy_createBatchScanner_result__isset __isset;

  void __set_success(const std::string& val);

  void __set_ouch1(const AccumuloException& val);

  void __set_ouch2(const AccumuloSecurityException& val);

  void __set_ouch3(const TableNotFoundException& val);

  bool operator == (const AccumuloProxy_createBatchScanner_result & rhs) const
  {
    if (!(success == rhs.success))
      return false;
    if (!(ouch1 == rhs.ouch1))
      return false;
    if (!(ouch2 == rhs.ouch2))
      return false;
    if (!(ouch3 == rhs.ouch3))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_createBatchScanner_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_createBatchScanner_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_createBatchScanner_presult__isset {
  _AccumuloProxy_createBatchScanner_presult__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
  bool success :1;
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_createBatchScanner_presult__isset;

class AccumuloProxy_createBatchScanner_presult {
 public:


  virtual ~AccumuloProxy_createBatchScanner_presult() throw();
  std::string* success;
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  TableNotFoundException ouch3;

  _AccumuloProxy_createBatchScanner_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_createScanner_args__isset {
  _AccumuloProxy_createScanner_args__isset() : login(false), tableName(false), options(false) {}
  bool login :1;
  bool tableName :1;
  bool options :1;
} _AccumuloProxy_createScanner_args__isset;

class AccumuloProxy_createScanner_args {
 public:

  AccumuloProxy_createScanner_args(const AccumuloProxy_createScanner_args&);
  AccumuloProxy_createScanner_args& operator=(const AccumuloProxy_createScanner_args&);
  AccumuloProxy_createScanner_args() : login(), tableName() {
  }

  virtual ~AccumuloProxy_createScanner_args() throw();
  std::string login;
  std::string tableName;
  ScanOptions options;

  _AccumuloProxy_createScanner_args__isset __isset;

  void __set_login(const std::string& val);

  void __set_tableName(const std::string& val);

  void __set_options(const ScanOptions& val);

  bool operator == (const AccumuloProxy_createScanner_args & rhs) const
  {
    if (!(login == rhs.login))
      return false;
    if (!(tableName == rhs.tableName))
      return false;
    if (!(options == rhs.options))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_createScanner_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_createScanner_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_createScanner_pargs {
 public:


  virtual ~AccumuloProxy_createScanner_pargs() throw();
  const std::string* login;
  const std::string* tableName;
  const ScanOptions* options;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_createScanner_result__isset {
  _AccumuloProxy_createScanner_result__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
  bool success :1;
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_createScanner_result__isset;

class AccumuloProxy_createScanner_result {
 public:

  AccumuloProxy_createScanner_result(const AccumuloProxy_createScanner_result&);
  AccumuloProxy_createScanner_result& operator=(const AccumuloProxy_createScanner_result&);
  AccumuloProxy_createScanner_result() : success() {
  }

  virtual ~AccumuloProxy_createScanner_result() throw();
  std::string success;
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  TableNotFoundException ouch3;

  _AccumuloProxy_createScanner_result__isset __isset;

  void __set_success(const std::string& val);

  void __set_ouch1(const AccumuloException& val);

  void __set_ouch2(const AccumuloSecurityException& val);

  void __set_ouch3(const TableNotFoundException& val);

  bool operator == (const AccumuloProxy_createScanner_result & rhs) const
  {
    if (!(success == rhs.success))
      return false;
    if (!(ouch1 == rhs.ouch1))
      return false;
    if (!(ouch2 == rhs.ouch2))
      return false;
    if (!(ouch3 == rhs.ouch3))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_createScanner_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_createScanner_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_createScanner_presult__isset {
  _AccumuloProxy_createScanner_presult__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
  bool success :1;
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_createScanner_presult__isset;

class AccumuloProxy_createScanner_presult {
 public:


  virtual ~AccumuloProxy_createScanner_presult() throw();
  std::string* success;
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  TableNotFoundException ouch3;

  _AccumuloProxy_createScanner_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_hasNext_args__isset {
  _AccumuloProxy_hasNext_args__isset() : scanner(false) {}
  bool scanner :1;
} _AccumuloProxy_hasNext_args__isset;

class AccumuloProxy_hasNext_args {
 public:

  AccumuloProxy_hasNext_args(const AccumuloProxy_hasNext_args&);
  AccumuloProxy_hasNext_args& operator=(const AccumuloProxy_hasNext_args&);
  AccumuloProxy_hasNext_args() : scanner() {
  }

  virtual ~AccumuloProxy_hasNext_args() throw();
  std::string scanner;

  _AccumuloProxy_hasNext_args__isset __isset;

  void __set_scanner(const std::string& val);

  bool operator == (const AccumuloProxy_hasNext_args & rhs) const
  {
    if (!(scanner == rhs.scanner))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_hasNext_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_hasNext_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_hasNext_pargs {
 public:


  virtual ~AccumuloProxy_hasNext_pargs() throw();
  const std::string* scanner;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_hasNext_result__isset {
  _AccumuloProxy_hasNext_result__isset() : success(false), ouch1(false) {}
  bool success :1;
  bool ouch1 :1;
} _AccumuloProxy_hasNext_result__isset;

class AccumuloProxy_hasNext_result {
 public:

  AccumuloProxy_hasNext_result(const AccumuloProxy_hasNext_result&);
  AccumuloProxy_hasNext_result& operator=(const AccumuloProxy_hasNext_result&);
  AccumuloProxy_hasNext_result() : success(0) {
  }

  virtual ~AccumuloProxy_hasNext_result() throw();
  bool success;
  UnknownScanner ouch1;

  _AccumuloProxy_hasNext_result__isset __isset;

  void __set_success(const bool val);

  void __set_ouch1(const UnknownScanner& val);

  bool operator == (const AccumuloProxy_hasNext_result & rhs) const
  {
    if (!(success == rhs.success))
      return false;
    if (!(ouch1 == rhs.ouch1))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_hasNext_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_hasNext_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_hasNext_presult__isset {
  _AccumuloProxy_hasNext_presult__isset() : success(false), ouch1(false) {}
  bool success :1;
  bool ouch1 :1;
} _AccumuloProxy_hasNext_presult__isset;

class AccumuloProxy_hasNext_presult {
 public:


  virtual ~AccumuloProxy_hasNext_presult() throw();
  bool* success;
  UnknownScanner ouch1;

  _AccumuloProxy_hasNext_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_nextEntry_args__isset {
  _AccumuloProxy_nextEntry_args__isset() : scanner(false) {}
  bool scanner :1;
} _AccumuloProxy_nextEntry_args__isset;

class AccumuloProxy_nextEntry_args {
 public:

  AccumuloProxy_nextEntry_args(const AccumuloProxy_nextEntry_args&);
  AccumuloProxy_nextEntry_args& operator=(const AccumuloProxy_nextEntry_args&);
  AccumuloProxy_nextEntry_args() : scanner() {
  }

  virtual ~AccumuloProxy_nextEntry_args() throw();
  std::string scanner;

  _AccumuloProxy_nextEntry_args__isset __isset;

  void __set_scanner(const std::string& val);

  bool operator == (const AccumuloProxy_nextEntry_args & rhs) const
  {
    if (!(scanner == rhs.scanner))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_nextEntry_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_nextEntry_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_nextEntry_pargs {
 public:


  virtual ~AccumuloProxy_nextEntry_pargs() throw();
  const std::string* scanner;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_nextEntry_result__isset {
  _AccumuloProxy_nextEntry_result__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
  bool success :1;
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_nextEntry_result__isset;

class AccumuloProxy_nextEntry_result {
 public:

  AccumuloProxy_nextEntry_result(const AccumuloProxy_nextEntry_result&);
  AccumuloProxy_nextEntry_result& operator=(const AccumuloProxy_nextEntry_result&);
  AccumuloProxy_nextEntry_result() {
  }

  virtual ~AccumuloProxy_nextEntry_result() throw();
  KeyValueAndPeek success;
  NoMoreEntriesException ouch1;
  UnknownScanner ouch2;
  AccumuloSecurityException ouch3;

  _AccumuloProxy_nextEntry_result__isset __isset;

  void __set_success(const KeyValueAndPeek& val);

  void __set_ouch1(const NoMoreEntriesException& val);

  void __set_ouch2(const UnknownScanner& val);

  void __set_ouch3(const AccumuloSecurityException& val);

  bool operator == (const AccumuloProxy_nextEntry_result & rhs) const
  {
    if (!(success == rhs.success))
      return false;
    if (!(ouch1 == rhs.ouch1))
      return false;
    if (!(ouch2 == rhs.ouch2))
      return false;
    if (!(ouch3 == rhs.ouch3))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_nextEntry_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_nextEntry_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_nextEntry_presult__isset {
  _AccumuloProxy_nextEntry_presult__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
  bool success :1;
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_nextEntry_presult__isset;

class AccumuloProxy_nextEntry_presult {
 public:


  virtual ~AccumuloProxy_nextEntry_presult() throw();
  KeyValueAndPeek* success;
  NoMoreEntriesException ouch1;
  UnknownScanner ouch2;
  AccumuloSecurityException ouch3;

  _AccumuloProxy_nextEntry_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_nextK_args__isset {
  _AccumuloProxy_nextK_args__isset() : scanner(false), k(false) {}
  bool scanner :1;
  bool k :1;
} _AccumuloProxy_nextK_args__isset;

class AccumuloProxy_nextK_args {
 public:

  AccumuloProxy_nextK_args(const AccumuloProxy_nextK_args&);
  AccumuloProxy_nextK_args& operator=(const AccumuloProxy_nextK_args&);
  AccumuloProxy_nextK_args() : scanner(), k(0) {
  }

  virtual ~AccumuloProxy_nextK_args() throw();
  std::string scanner;
  int32_t k;

  _AccumuloProxy_nextK_args__isset __isset;

  void __set_scanner(const std::string& val);

  void __set_k(const int32_t val);

  bool operator == (const AccumuloProxy_nextK_args & rhs) const
  {
    if (!(scanner == rhs.scanner))
      return false;
    if (!(k == rhs.k))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_nextK_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_nextK_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_nextK_pargs {
 public:


  virtual ~AccumuloProxy_nextK_pargs() throw();
  const std::string* scanner;
  const int32_t* k;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_nextK_result__isset {
  _AccumuloProxy_nextK_result__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
  bool success :1;
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_nextK_result__isset;

class AccumuloProxy_nextK_result {
 public:

  AccumuloProxy_nextK_result(const AccumuloProxy_nextK_result&);
  AccumuloProxy_nextK_result& operator=(const AccumuloProxy_nextK_result&);
  AccumuloProxy_nextK_result() {
  }

  virtual ~AccumuloProxy_nextK_result() throw();
  ScanResult success;
  NoMoreEntriesException ouch1;
  UnknownScanner ouch2;
  AccumuloSecurityException ouch3;

  _AccumuloProxy_nextK_result__isset __isset;

  void __set_success(const ScanResult& val);

  void __set_ouch1(const NoMoreEntriesException& val);

  void __set_ouch2(const UnknownScanner& val);

  void __set_ouch3(const AccumuloSecurityException& val);

  bool operator == (const AccumuloProxy_nextK_result & rhs) const
  {
    if (!(success == rhs.success))
      return false;
    if (!(ouch1 == rhs.ouch1))
      return false;
    if (!(ouch2 == rhs.ouch2))
      return false;
    if (!(ouch3 == rhs.ouch3))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_nextK_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_nextK_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_nextK_presult__isset {
  _AccumuloProxy_nextK_presult__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
  bool success :1;
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_nextK_presult__isset;

class AccumuloProxy_nextK_presult {
 public:


  virtual ~AccumuloProxy_nextK_presult() throw();
  ScanResult* success;
  NoMoreEntriesException ouch1;
  UnknownScanner ouch2;
  AccumuloSecurityException ouch3;

  _AccumuloProxy_nextK_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_closeScanner_args__isset {
  _AccumuloProxy_closeScanner_args__isset() : scanner(false) {}
  bool scanner :1;
} _AccumuloProxy_closeScanner_args__isset;

class AccumuloProxy_closeScanner_args {
 public:

  AccumuloProxy_closeScanner_args(const AccumuloProxy_closeScanner_args&);
  AccumuloProxy_closeScanner_args& operator=(const AccumuloProxy_closeScanner_args&);
  AccumuloProxy_closeScanner_args() : scanner() {
  }

  virtual ~AccumuloProxy_closeScanner_args() throw();
  std::string scanner;

  _AccumuloProxy_closeScanner_args__isset __isset;

  void __set_scanner(const std::string& val);

  bool operator == (const AccumuloProxy_closeScanner_args & rhs) const
  {
    if (!(scanner == rhs.scanner))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_closeScanner_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_closeScanner_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_closeScanner_pargs {
 public:


  virtual ~AccumuloProxy_closeScanner_pargs() throw();
  const std::string* scanner;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_closeScanner_result__isset {
  _AccumuloProxy_closeScanner_result__isset() : ouch1(false) {}
  bool ouch1 :1;
} _AccumuloProxy_closeScanner_result__isset;

class AccumuloProxy_closeScanner_result {
 public:

  AccumuloProxy_closeScanner_result(const AccumuloProxy_closeScanner_result&);
  AccumuloProxy_closeScanner_result& operator=(const AccumuloProxy_closeScanner_result&);
  AccumuloProxy_closeScanner_result() {
  }

  virtual ~AccumuloProxy_closeScanner_result() throw();
  UnknownScanner ouch1;

  _AccumuloProxy_closeScanner_result__isset __isset;

  void __set_ouch1(const UnknownScanner& val);

  bool operator == (const AccumuloProxy_closeScanner_result & rhs) const
  {
    if (!(ouch1 == rhs.ouch1))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_closeScanner_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_closeScanner_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_closeScanner_presult__isset {
  _AccumuloProxy_closeScanner_presult__isset() : ouch1(false) {}
  bool ouch1 :1;
} _AccumuloProxy_closeScanner_presult__isset;

class AccumuloProxy_closeScanner_presult {
 public:


  virtual ~AccumuloProxy_closeScanner_presult() throw();
  UnknownScanner ouch1;

  _AccumuloProxy_closeScanner_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_updateAndFlush_args__isset {
  _AccumuloProxy_updateAndFlush_args__isset() : login(false), tableName(false), cells(false) {}
  bool login :1;
  bool tableName :1;
  bool cells :1;
} _AccumuloProxy_updateAndFlush_args__isset;

class AccumuloProxy_updateAndFlush_args {
 public:

  AccumuloProxy_updateAndFlush_args(const AccumuloProxy_updateAndFlush_args&);
  AccumuloProxy_updateAndFlush_args& operator=(const AccumuloProxy_updateAndFlush_args&);
  AccumuloProxy_updateAndFlush_args() : login(), tableName() {
  }

  virtual ~AccumuloProxy_updateAndFlush_args() throw();
  std::string login;
  std::string tableName;
  std::map<std::string, std::vector<ColumnUpdate> >  cells;

  _AccumuloProxy_updateAndFlush_args__isset __isset;

  void __set_login(const std::string& val);

  void __set_tableName(const std::string& val);

  void __set_cells(const std::map<std::string, std::vector<ColumnUpdate> > & val);

  bool operator == (const AccumuloProxy_updateAndFlush_args & rhs) const
  {
    if (!(login == rhs.login))
      return false;
    if (!(tableName == rhs.tableName))
      return false;
    if (!(cells == rhs.cells))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_updateAndFlush_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_updateAndFlush_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_updateAndFlush_pargs {
 public:


  virtual ~AccumuloProxy_updateAndFlush_pargs() throw();
  const std::string* login;
  const std::string* tableName;
  const std::map<std::string, std::vector<ColumnUpdate> > * cells;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_updateAndFlush_result__isset {
  _AccumuloProxy_updateAndFlush_result__isset() : outch1(false), ouch2(false), ouch3(false), ouch4(false) {}
  bool outch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
  bool ouch4 :1;
} _AccumuloProxy_updateAndFlush_result__isset;

class AccumuloProxy_updateAndFlush_result {
 public:

  AccumuloProxy_updateAndFlush_result(const AccumuloProxy_updateAndFlush_result&);
  AccumuloProxy_updateAndFlush_result& operator=(const AccumuloProxy_updateAndFlush_result&);
  AccumuloProxy_updateAndFlush_result() {
  }

  virtual ~AccumuloProxy_updateAndFlush_result() throw();
  AccumuloException outch1;
  AccumuloSecurityException ouch2;
  TableNotFoundException ouch3;
  MutationsRejectedException ouch4;

  _AccumuloProxy_updateAndFlush_result__isset __isset;

  void __set_outch1(const AccumuloException& val);

  void __set_ouch2(const AccumuloSecurityException& val);

  void __set_ouch3(const TableNotFoundException& val);

  void __set_ouch4(const MutationsRejectedException& val);

  bool operator == (const AccumuloProxy_updateAndFlush_result & rhs) const
  {
    if (!(outch1 == rhs.outch1))
      return false;
    if (!(ouch2 == rhs.ouch2))
      return false;
    if (!(ouch3 == rhs.ouch3))
      return false;
    if (!(ouch4 == rhs.ouch4))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_updateAndFlush_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_updateAndFlush_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_updateAndFlush_presult__isset {
  _AccumuloProxy_updateAndFlush_presult__isset() : outch1(false), ouch2(false), ouch3(false), ouch4(false) {}
  bool outch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
  bool ouch4 :1;
} _AccumuloProxy_updateAndFlush_presult__isset;

class AccumuloProxy_updateAndFlush_presult {
 public:


  virtual ~AccumuloProxy_updateAndFlush_presult() throw();
  AccumuloException outch1;
  AccumuloSecurityException ouch2;
  TableNotFoundException ouch3;
  MutationsRejectedException ouch4;

  _AccumuloProxy_updateAndFlush_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_createWriter_args__isset {
  _AccumuloProxy_createWriter_args__isset() : login(false), tableName(false), opts(false) {}
  bool login :1;
  bool tableName :1;
  bool opts :1;
} _AccumuloProxy_createWriter_args__isset;

class AccumuloProxy_createWriter_args {
 public:

  AccumuloProxy_createWriter_args(const AccumuloProxy_createWriter_args&);
  AccumuloProxy_createWriter_args& operator=(const AccumuloProxy_createWriter_args&);
  AccumuloProxy_createWriter_args() : login(), tableName() {
  }

  virtual ~AccumuloProxy_createWriter_args() throw();
  std::string login;
  std::string tableName;
  WriterOptions opts;

  _AccumuloProxy_createWriter_args__isset __isset;

  void __set_login(const std::string& val);

  void __set_tableName(const std::string& val);

  void __set_opts(const WriterOptions& val);

  bool operator == (const AccumuloProxy_createWriter_args & rhs) const
  {
    if (!(login == rhs.login))
      return false;
    if (!(tableName == rhs.tableName))
      return false;
    if (!(opts == rhs.opts))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_createWriter_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_createWriter_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_createWriter_pargs {
 public:


  virtual ~AccumuloProxy_createWriter_pargs() throw();
  const std::string* login;
  const std::string* tableName;
  const WriterOptions* opts;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_createWriter_result__isset {
  _AccumuloProxy_createWriter_result__isset() : success(false), outch1(false), ouch2(false), ouch3(false) {}
  bool success :1;
  bool outch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_createWriter_result__isset;

class AccumuloProxy_createWriter_result {
 public:

  AccumuloProxy_createWriter_result(const AccumuloProxy_createWriter_result&);
  AccumuloProxy_createWriter_result& operator=(const AccumuloProxy_createWriter_result&);
  AccumuloProxy_createWriter_result() : success() {
  }

  virtual ~AccumuloProxy_createWriter_result() throw();
  std::string success;
  AccumuloException outch1;
  AccumuloSecurityException ouch2;
  TableNotFoundException ouch3;

  _AccumuloProxy_createWriter_result__isset __isset;

  void __set_success(const std::string& val);

  void __set_outch1(const AccumuloException& val);

  void __set_ouch2(const AccumuloSecurityException& val);

  void __set_ouch3(const TableNotFoundException& val);

  bool operator == (const AccumuloProxy_createWriter_result & rhs) const
  {
    if (!(success == rhs.success))
      return false;
    if (!(outch1 == rhs.outch1))
      return false;
    if (!(ouch2 == rhs.ouch2))
      return false;
    if (!(ouch3 == rhs.ouch3))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_createWriter_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_createWriter_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_createWriter_presult__isset {
  _AccumuloProxy_createWriter_presult__isset() : success(false), outch1(false), ouch2(false), ouch3(false) {}
  bool success :1;
  bool outch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_createWriter_presult__isset;

class AccumuloProxy_createWriter_presult {
 public:


  virtual ~AccumuloProxy_createWriter_presult() throw();
  std::string* success;
  AccumuloException outch1;
  AccumuloSecurityException ouch2;
  TableNotFoundException ouch3;

  _AccumuloProxy_createWriter_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_update_args__isset {
  _AccumuloProxy_update_args__isset() : writer(false), cells(false) {}
  bool writer :1;
  bool cells :1;
} _AccumuloProxy_update_args__isset;

class AccumuloProxy_update_args {
 public:

  AccumuloProxy_update_args(const AccumuloProxy_update_args&);
  AccumuloProxy_update_args& operator=(const AccumuloProxy_update_args&);
  AccumuloProxy_update_args() : writer() {
  }

  virtual ~AccumuloProxy_update_args() throw();
  std::string writer;
  std::map<std::string, std::vector<ColumnUpdate> >  cells;

  _AccumuloProxy_update_args__isset __isset;

  void __set_writer(const std::string& val);

  void __set_cells(const std::map<std::string, std::vector<ColumnUpdate> > & val);

  bool operator == (const AccumuloProxy_update_args & rhs) const
  {
    if (!(writer == rhs.writer))
      return false;
    if (!(cells == rhs.cells))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_update_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_update_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_update_pargs {
 public:


  virtual ~AccumuloProxy_update_pargs() throw();
  const std::string* writer;
  const std::map<std::string, std::vector<ColumnUpdate> > * cells;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_flush_args__isset {
  _AccumuloProxy_flush_args__isset() : writer(false) {}
  bool writer :1;
} _AccumuloProxy_flush_args__isset;

class AccumuloProxy_flush_args {
 public:

  AccumuloProxy_flush_args(const AccumuloProxy_flush_args&);
  AccumuloProxy_flush_args& operator=(const AccumuloProxy_flush_args&);
  AccumuloProxy_flush_args() : writer() {
  }

  virtual ~AccumuloProxy_flush_args() throw();
  std::string writer;

  _AccumuloProxy_flush_args__isset __isset;

  void __set_writer(const std::string& val);

  bool operator == (const AccumuloProxy_flush_args & rhs) const
  {
    if (!(writer == rhs.writer))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_flush_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_flush_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_flush_pargs {
 public:


  virtual ~AccumuloProxy_flush_pargs() throw();
  const std::string* writer;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_flush_result__isset {
  _AccumuloProxy_flush_result__isset() : ouch1(false), ouch2(false) {}
  bool ouch1 :1;
  bool ouch2 :1;
} _AccumuloProxy_flush_result__isset;

class AccumuloProxy_flush_result {
 public:

  AccumuloProxy_flush_result(const AccumuloProxy_flush_result&);
  AccumuloProxy_flush_result& operator=(const AccumuloProxy_flush_result&);
  AccumuloProxy_flush_result() {
  }

  virtual ~AccumuloProxy_flush_result() throw();
  UnknownWriter ouch1;
  MutationsRejectedException ouch2;

  _AccumuloProxy_flush_result__isset __isset;

  void __set_ouch1(const UnknownWriter& val);

  void __set_ouch2(const MutationsRejectedException& val);

  bool operator == (const AccumuloProxy_flush_result & rhs) const
  {
    if (!(ouch1 == rhs.ouch1))
      return false;
    if (!(ouch2 == rhs.ouch2))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_flush_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_flush_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_flush_presult__isset {
  _AccumuloProxy_flush_presult__isset() : ouch1(false), ouch2(false) {}
  bool ouch1 :1;
  bool ouch2 :1;
} _AccumuloProxy_flush_presult__isset;

class AccumuloProxy_flush_presult {
 public:


  virtual ~AccumuloProxy_flush_presult() throw();
  UnknownWriter ouch1;
  MutationsRejectedException ouch2;

  _AccumuloProxy_flush_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_closeWriter_args__isset {
  _AccumuloProxy_closeWriter_args__isset() : writer(false) {}
  bool writer :1;
} _AccumuloProxy_closeWriter_args__isset;

class AccumuloProxy_closeWriter_args {
 public:

  AccumuloProxy_closeWriter_args(const AccumuloProxy_closeWriter_args&);
  AccumuloProxy_closeWriter_args& operator=(const AccumuloProxy_closeWriter_args&);
  AccumuloProxy_closeWriter_args() : writer() {
  }

  virtual ~AccumuloProxy_closeWriter_args() throw();
  std::string writer;

  _AccumuloProxy_closeWriter_args__isset __isset;

  void __set_writer(const std::string& val);

  bool operator == (const AccumuloProxy_closeWriter_args & rhs) const
  {
    if (!(writer == rhs.writer))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_closeWriter_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_closeWriter_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_closeWriter_pargs {
 public:


  virtual ~AccumuloProxy_closeWriter_pargs() throw();
  const std::string* writer;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_closeWriter_result__isset {
  _AccumuloProxy_closeWriter_result__isset() : ouch1(false), ouch2(false) {}
  bool ouch1 :1;
  bool ouch2 :1;
} _AccumuloProxy_closeWriter_result__isset;

class AccumuloProxy_closeWriter_result {
 public:

  AccumuloProxy_closeWriter_result(const AccumuloProxy_closeWriter_result&);
  AccumuloProxy_closeWriter_result& operator=(const AccumuloProxy_closeWriter_result&);
  AccumuloProxy_closeWriter_result() {
  }

  virtual ~AccumuloProxy_closeWriter_result() throw();
  UnknownWriter ouch1;
  MutationsRejectedException ouch2;

  _AccumuloProxy_closeWriter_result__isset __isset;

  void __set_ouch1(const UnknownWriter& val);

  void __set_ouch2(const MutationsRejectedException& val);

  bool operator == (const AccumuloProxy_closeWriter_result & rhs) const
  {
    if (!(ouch1 == rhs.ouch1))
      return false;
    if (!(ouch2 == rhs.ouch2))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_closeWriter_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_closeWriter_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_closeWriter_presult__isset {
  _AccumuloProxy_closeWriter_presult__isset() : ouch1(false), ouch2(false) {}
  bool ouch1 :1;
  bool ouch2 :1;
} _AccumuloProxy_closeWriter_presult__isset;

class AccumuloProxy_closeWriter_presult {
 public:


  virtual ~AccumuloProxy_closeWriter_presult() throw();
  UnknownWriter ouch1;
  MutationsRejectedException ouch2;

  _AccumuloProxy_closeWriter_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_updateRowConditionally_args__isset {
  _AccumuloProxy_updateRowConditionally_args__isset() : login(false), tableName(false), row(false), updates(false) {}
  bool login :1;
  bool tableName :1;
  bool row :1;
  bool updates :1;
} _AccumuloProxy_updateRowConditionally_args__isset;

class AccumuloProxy_updateRowConditionally_args {
 public:

  AccumuloProxy_updateRowConditionally_args(const AccumuloProxy_updateRowConditionally_args&);
  AccumuloProxy_updateRowConditionally_args& operator=(const AccumuloProxy_updateRowConditionally_args&);
  AccumuloProxy_updateRowConditionally_args() : login(), tableName(), row() {
  }

  virtual ~AccumuloProxy_updateRowConditionally_args() throw();
  std::string login;
  std::string tableName;
  std::string row;
  ConditionalUpdates updates;

  _AccumuloProxy_updateRowConditionally_args__isset __isset;

  void __set_login(const std::string& val);

  void __set_tableName(const std::string& val);

  void __set_row(const std::string& val);

  void __set_updates(const ConditionalUpdates& val);

  bool operator == (const AccumuloProxy_updateRowConditionally_args & rhs) const
  {
    if (!(login == rhs.login))
      return false;
    if (!(tableName == rhs.tableName))
      return false;
    if (!(row == rhs.row))
      return false;
    if (!(updates == rhs.updates))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_updateRowConditionally_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_updateRowConditionally_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_updateRowConditionally_pargs {
 public:


  virtual ~AccumuloProxy_updateRowConditionally_pargs() throw();
  const std::string* login;
  const std::string* tableName;
  const std::string* row;
  const ConditionalUpdates* updates;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_updateRowConditionally_result__isset {
  _AccumuloProxy_updateRowConditionally_result__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
  bool success :1;
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_updateRowConditionally_result__isset;

class AccumuloProxy_updateRowConditionally_result {
 public:

  AccumuloProxy_updateRowConditionally_result(const AccumuloProxy_updateRowConditionally_result&);
  AccumuloProxy_updateRowConditionally_result& operator=(const AccumuloProxy_updateRowConditionally_result&);
  AccumuloProxy_updateRowConditionally_result() : success((ConditionalStatus::type)0) {
  }

  virtual ~AccumuloProxy_updateRowConditionally_result() throw();
  ConditionalStatus::type success;
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  TableNotFoundException ouch3;

  _AccumuloProxy_updateRowConditionally_result__isset __isset;

  void __set_success(const ConditionalStatus::type val);

  void __set_ouch1(const AccumuloException& val);

  void __set_ouch2(const AccumuloSecurityException& val);

  void __set_ouch3(const TableNotFoundException& val);

  bool operator == (const AccumuloProxy_updateRowConditionally_result & rhs) const
  {
    if (!(success == rhs.success))
      return false;
    if (!(ouch1 == rhs.ouch1))
      return false;
    if (!(ouch2 == rhs.ouch2))
      return false;
    if (!(ouch3 == rhs.ouch3))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_updateRowConditionally_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_updateRowConditionally_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_updateRowConditionally_presult__isset {
  _AccumuloProxy_updateRowConditionally_presult__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
  bool success :1;
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_updateRowConditionally_presult__isset;

class AccumuloProxy_updateRowConditionally_presult {
 public:


  virtual ~AccumuloProxy_updateRowConditionally_presult() throw();
  ConditionalStatus::type* success;
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  TableNotFoundException ouch3;

  _AccumuloProxy_updateRowConditionally_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_createConditionalWriter_args__isset {
  _AccumuloProxy_createConditionalWriter_args__isset() : login(false), tableName(false), options(false) {}
  bool login :1;
  bool tableName :1;
  bool options :1;
} _AccumuloProxy_createConditionalWriter_args__isset;

class AccumuloProxy_createConditionalWriter_args {
 public:

  AccumuloProxy_createConditionalWriter_args(const AccumuloProxy_createConditionalWriter_args&);
  AccumuloProxy_createConditionalWriter_args& operator=(const AccumuloProxy_createConditionalWriter_args&);
  AccumuloProxy_createConditionalWriter_args() : login(), tableName() {
  }

  virtual ~AccumuloProxy_createConditionalWriter_args() throw();
  std::string login;
  std::string tableName;
  ConditionalWriterOptions options;

  _AccumuloProxy_createConditionalWriter_args__isset __isset;

  void __set_login(const std::string& val);

  void __set_tableName(const std::string& val);

  void __set_options(const ConditionalWriterOptions& val);

  bool operator == (const AccumuloProxy_createConditionalWriter_args & rhs) const
  {
    if (!(login == rhs.login))
      return false;
    if (!(tableName == rhs.tableName))
      return false;
    if (!(options == rhs.options))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_createConditionalWriter_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_createConditionalWriter_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_createConditionalWriter_pargs {
 public:


  virtual ~AccumuloProxy_createConditionalWriter_pargs() throw();
  const std::string* login;
  const std::string* tableName;
  const ConditionalWriterOptions* options;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_createConditionalWriter_result__isset {
  _AccumuloProxy_createConditionalWriter_result__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
  bool success :1;
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_createConditionalWriter_result__isset;

class AccumuloProxy_createConditionalWriter_result {
 public:

  AccumuloProxy_createConditionalWriter_result(const AccumuloProxy_createConditionalWriter_result&);
  AccumuloProxy_createConditionalWriter_result& operator=(const AccumuloProxy_createConditionalWriter_result&);
  AccumuloProxy_createConditionalWriter_result() : success() {
  }

  virtual ~AccumuloProxy_createConditionalWriter_result() throw();
  std::string success;
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  TableNotFoundException ouch3;

  _AccumuloProxy_createConditionalWriter_result__isset __isset;

  void __set_success(const std::string& val);

  void __set_ouch1(const AccumuloException& val);

  void __set_ouch2(const AccumuloSecurityException& val);

  void __set_ouch3(const TableNotFoundException& val);

  bool operator == (const AccumuloProxy_createConditionalWriter_result & rhs) const
  {
    if (!(success == rhs.success))
      return false;
    if (!(ouch1 == rhs.ouch1))
      return false;
    if (!(ouch2 == rhs.ouch2))
      return false;
    if (!(ouch3 == rhs.ouch3))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_createConditionalWriter_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_createConditionalWriter_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_createConditionalWriter_presult__isset {
  _AccumuloProxy_createConditionalWriter_presult__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
  bool success :1;
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_createConditionalWriter_presult__isset;

class AccumuloProxy_createConditionalWriter_presult {
 public:


  virtual ~AccumuloProxy_createConditionalWriter_presult() throw();
  std::string* success;
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  TableNotFoundException ouch3;

  _AccumuloProxy_createConditionalWriter_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_updateRowsConditionally_args__isset {
  _AccumuloProxy_updateRowsConditionally_args__isset() : conditionalWriter(false), updates(false) {}
  bool conditionalWriter :1;
  bool updates :1;
} _AccumuloProxy_updateRowsConditionally_args__isset;

class AccumuloProxy_updateRowsConditionally_args {
 public:

  AccumuloProxy_updateRowsConditionally_args(const AccumuloProxy_updateRowsConditionally_args&);
  AccumuloProxy_updateRowsConditionally_args& operator=(const AccumuloProxy_updateRowsConditionally_args&);
  AccumuloProxy_updateRowsConditionally_args() : conditionalWriter() {
  }

  virtual ~AccumuloProxy_updateRowsConditionally_args() throw();
  std::string conditionalWriter;
  std::map<std::string, ConditionalUpdates>  updates;

  _AccumuloProxy_updateRowsConditionally_args__isset __isset;

  void __set_conditionalWriter(const std::string& val);

  void __set_updates(const std::map<std::string, ConditionalUpdates> & val);

  bool operator == (const AccumuloProxy_updateRowsConditionally_args & rhs) const
  {
    if (!(conditionalWriter == rhs.conditionalWriter))
      return false;
    if (!(updates == rhs.updates))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_updateRowsConditionally_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_updateRowsConditionally_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_updateRowsConditionally_pargs {
 public:


  virtual ~AccumuloProxy_updateRowsConditionally_pargs() throw();
  const std::string* conditionalWriter;
  const std::map<std::string, ConditionalUpdates> * updates;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_updateRowsConditionally_result__isset {
  _AccumuloProxy_updateRowsConditionally_result__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
  bool success :1;
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_updateRowsConditionally_result__isset;

class AccumuloProxy_updateRowsConditionally_result {
 public:

  AccumuloProxy_updateRowsConditionally_result(const AccumuloProxy_updateRowsConditionally_result&);
  AccumuloProxy_updateRowsConditionally_result& operator=(const AccumuloProxy_updateRowsConditionally_result&);
  AccumuloProxy_updateRowsConditionally_result() {
  }

  virtual ~AccumuloProxy_updateRowsConditionally_result() throw();
  std::map<std::string, ConditionalStatus::type>  success;
  UnknownWriter ouch1;
  AccumuloException ouch2;
  AccumuloSecurityException ouch3;

  _AccumuloProxy_updateRowsConditionally_result__isset __isset;

  void __set_success(const std::map<std::string, ConditionalStatus::type> & val);

  void __set_ouch1(const UnknownWriter& val);

  void __set_ouch2(const AccumuloException& val);

  void __set_ouch3(const AccumuloSecurityException& val);

  bool operator == (const AccumuloProxy_updateRowsConditionally_result & rhs) const
  {
    if (!(success == rhs.success))
      return false;
    if (!(ouch1 == rhs.ouch1))
      return false;
    if (!(ouch2 == rhs.ouch2))
      return false;
    if (!(ouch3 == rhs.ouch3))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_updateRowsConditionally_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_updateRowsConditionally_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_updateRowsConditionally_presult__isset {
  _AccumuloProxy_updateRowsConditionally_presult__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
  bool success :1;
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_updateRowsConditionally_presult__isset;

class AccumuloProxy_updateRowsConditionally_presult {
 public:


  virtual ~AccumuloProxy_updateRowsConditionally_presult() throw();
  std::map<std::string, ConditionalStatus::type> * success;
  UnknownWriter ouch1;
  AccumuloException ouch2;
  AccumuloSecurityException ouch3;

  _AccumuloProxy_updateRowsConditionally_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_closeConditionalWriter_args__isset {
  _AccumuloProxy_closeConditionalWriter_args__isset() : conditionalWriter(false) {}
  bool conditionalWriter :1;
} _AccumuloProxy_closeConditionalWriter_args__isset;

class AccumuloProxy_closeConditionalWriter_args {
 public:

  AccumuloProxy_closeConditionalWriter_args(const AccumuloProxy_closeConditionalWriter_args&);
  AccumuloProxy_closeConditionalWriter_args& operator=(const AccumuloProxy_closeConditionalWriter_args&);
  AccumuloProxy_closeConditionalWriter_args() : conditionalWriter() {
  }

  virtual ~AccumuloProxy_closeConditionalWriter_args() throw();
  std::string conditionalWriter;

  _AccumuloProxy_closeConditionalWriter_args__isset __isset;

  void __set_conditionalWriter(const std::string& val);

  bool operator == (const AccumuloProxy_closeConditionalWriter_args & rhs) const
  {
    if (!(conditionalWriter == rhs.conditionalWriter))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_closeConditionalWriter_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_closeConditionalWriter_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_closeConditionalWriter_pargs {
 public:


  virtual ~AccumuloProxy_closeConditionalWriter_pargs() throw();
  const std::string* conditionalWriter;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_closeConditionalWriter_result {
 public:

  AccumuloProxy_closeConditionalWriter_result(const AccumuloProxy_closeConditionalWriter_result&);
  AccumuloProxy_closeConditionalWriter_result& operator=(const AccumuloProxy_closeConditionalWriter_result&);
  AccumuloProxy_closeConditionalWriter_result() {
  }

  virtual ~AccumuloProxy_closeConditionalWriter_result() throw();

  bool operator == (const AccumuloProxy_closeConditionalWriter_result & /* rhs */) const
  {
    return true;
  }
  bool operator != (const AccumuloProxy_closeConditionalWriter_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_closeConditionalWriter_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_closeConditionalWriter_presult {
 public:


  virtual ~AccumuloProxy_closeConditionalWriter_presult() throw();

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_getRowRange_args__isset {
  _AccumuloProxy_getRowRange_args__isset() : row(false) {}
  bool row :1;
} _AccumuloProxy_getRowRange_args__isset;

class AccumuloProxy_getRowRange_args {
 public:

  AccumuloProxy_getRowRange_args(const AccumuloProxy_getRowRange_args&);
  AccumuloProxy_getRowRange_args& operator=(const AccumuloProxy_getRowRange_args&);
  AccumuloProxy_getRowRange_args() : row() {
  }

  virtual ~AccumuloProxy_getRowRange_args() throw();
  std::string row;

  _AccumuloProxy_getRowRange_args__isset __isset;

  void __set_row(const std::string& val);

  bool operator == (const AccumuloProxy_getRowRange_args & rhs) const
  {
    if (!(row == rhs.row))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_getRowRange_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_getRowRange_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_getRowRange_pargs {
 public:


  virtual ~AccumuloProxy_getRowRange_pargs() throw();
  const std::string* row;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_getRowRange_result__isset {
  _AccumuloProxy_getRowRange_result__isset() : success(false) {}
  bool success :1;
} _AccumuloProxy_getRowRange_result__isset;

class AccumuloProxy_getRowRange_result {
 public:

  AccumuloProxy_getRowRange_result(const AccumuloProxy_getRowRange_result&);
  AccumuloProxy_getRowRange_result& operator=(const AccumuloProxy_getRowRange_result&);
  AccumuloProxy_getRowRange_result() {
  }

  virtual ~AccumuloProxy_getRowRange_result() throw();
  Range success;

  _AccumuloProxy_getRowRange_result__isset __isset;

  void __set_success(const Range& val);

  bool operator == (const AccumuloProxy_getRowRange_result & rhs) const
  {
    if (!(success == rhs.success))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_getRowRange_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_getRowRange_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_getRowRange_presult__isset {
  _AccumuloProxy_getRowRange_presult__isset() : success(false) {}
  bool success :1;
} _AccumuloProxy_getRowRange_presult__isset;

class AccumuloProxy_getRowRange_presult {
 public:


  virtual ~AccumuloProxy_getRowRange_presult() throw();
  Range* success;

  _AccumuloProxy_getRowRange_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_getFollowing_args__isset {
  _AccumuloProxy_getFollowing_args__isset() : key(false), part(false) {}
  bool key :1;
  bool part :1;
} _AccumuloProxy_getFollowing_args__isset;

class AccumuloProxy_getFollowing_args {
 public:

  AccumuloProxy_getFollowing_args(const AccumuloProxy_getFollowing_args&);
  AccumuloProxy_getFollowing_args& operator=(const AccumuloProxy_getFollowing_args&);
  AccumuloProxy_getFollowing_args() : part((PartialKey::type)0) {
  }

  virtual ~AccumuloProxy_getFollowing_args() throw();
  Key key;
  PartialKey::type part;

  _AccumuloProxy_getFollowing_args__isset __isset;

  void __set_key(const Key& val);

  void __set_part(const PartialKey::type val);

  bool operator == (const AccumuloProxy_getFollowing_args & rhs) const
  {
    if (!(key == rhs.key))
      return false;
    if (!(part == rhs.part))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_getFollowing_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_getFollowing_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_getFollowing_pargs {
 public:


  virtual ~AccumuloProxy_getFollowing_pargs() throw();
  const Key* key;
  const PartialKey::type* part;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_getFollowing_result__isset {
  _AccumuloProxy_getFollowing_result__isset() : success(false) {}
  bool success :1;
} _AccumuloProxy_getFollowing_result__isset;

class AccumuloProxy_getFollowing_result {
 public:

  AccumuloProxy_getFollowing_result(const AccumuloProxy_getFollowing_result&);
  AccumuloProxy_getFollowing_result& operator=(const AccumuloProxy_getFollowing_result&);
  AccumuloProxy_getFollowing_result() {
  }

  virtual ~AccumuloProxy_getFollowing_result() throw();
  Key success;

  _AccumuloProxy_getFollowing_result__isset __isset;

  void __set_success(const Key& val);

  bool operator == (const AccumuloProxy_getFollowing_result & rhs) const
  {
    if (!(success == rhs.success))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_getFollowing_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_getFollowing_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_getFollowing_presult__isset {
  _AccumuloProxy_getFollowing_presult__isset() : success(false) {}
  bool success :1;
} _AccumuloProxy_getFollowing_presult__isset;

class AccumuloProxy_getFollowing_presult {
 public:


  virtual ~AccumuloProxy_getFollowing_presult() throw();
  Key* success;

  _AccumuloProxy_getFollowing_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};


class AccumuloProxy_systemNamespace_args {
 public:

  AccumuloProxy_systemNamespace_args(const AccumuloProxy_systemNamespace_args&);
  AccumuloProxy_systemNamespace_args& operator=(const AccumuloProxy_systemNamespace_args&);
  AccumuloProxy_systemNamespace_args() {
  }

  virtual ~AccumuloProxy_systemNamespace_args() throw();

  bool operator == (const AccumuloProxy_systemNamespace_args & /* rhs */) const
  {
    return true;
  }
  bool operator != (const AccumuloProxy_systemNamespace_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_systemNamespace_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_systemNamespace_pargs {
 public:


  virtual ~AccumuloProxy_systemNamespace_pargs() throw();

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_systemNamespace_result__isset {
  _AccumuloProxy_systemNamespace_result__isset() : success(false) {}
  bool success :1;
} _AccumuloProxy_systemNamespace_result__isset;

class AccumuloProxy_systemNamespace_result {
 public:

  AccumuloProxy_systemNamespace_result(const AccumuloProxy_systemNamespace_result&);
  AccumuloProxy_systemNamespace_result& operator=(const AccumuloProxy_systemNamespace_result&);
  AccumuloProxy_systemNamespace_result() : success() {
  }

  virtual ~AccumuloProxy_systemNamespace_result() throw();
  std::string success;

  _AccumuloProxy_systemNamespace_result__isset __isset;

  void __set_success(const std::string& val);

  bool operator == (const AccumuloProxy_systemNamespace_result & rhs) const
  {
    if (!(success == rhs.success))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_systemNamespace_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_systemNamespace_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_systemNamespace_presult__isset {
  _AccumuloProxy_systemNamespace_presult__isset() : success(false) {}
  bool success :1;
} _AccumuloProxy_systemNamespace_presult__isset;

class AccumuloProxy_systemNamespace_presult {
 public:


  virtual ~AccumuloProxy_systemNamespace_presult() throw();
  std::string* success;

  _AccumuloProxy_systemNamespace_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};


class AccumuloProxy_defaultNamespace_args {
 public:

  AccumuloProxy_defaultNamespace_args(const AccumuloProxy_defaultNamespace_args&);
  AccumuloProxy_defaultNamespace_args& operator=(const AccumuloProxy_defaultNamespace_args&);
  AccumuloProxy_defaultNamespace_args() {
  }

  virtual ~AccumuloProxy_defaultNamespace_args() throw();

  bool operator == (const AccumuloProxy_defaultNamespace_args & /* rhs */) const
  {
    return true;
  }
  bool operator != (const AccumuloProxy_defaultNamespace_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_defaultNamespace_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_defaultNamespace_pargs {
 public:


  virtual ~AccumuloProxy_defaultNamespace_pargs() throw();

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_defaultNamespace_result__isset {
  _AccumuloProxy_defaultNamespace_result__isset() : success(false) {}
  bool success :1;
} _AccumuloProxy_defaultNamespace_result__isset;

class AccumuloProxy_defaultNamespace_result {
 public:

  AccumuloProxy_defaultNamespace_result(const AccumuloProxy_defaultNamespace_result&);
  AccumuloProxy_defaultNamespace_result& operator=(const AccumuloProxy_defaultNamespace_result&);
  AccumuloProxy_defaultNamespace_result() : success() {
  }

  virtual ~AccumuloProxy_defaultNamespace_result() throw();
  std::string success;

  _AccumuloProxy_defaultNamespace_result__isset __isset;

  void __set_success(const std::string& val);

  bool operator == (const AccumuloProxy_defaultNamespace_result & rhs) const
  {
    if (!(success == rhs.success))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_defaultNamespace_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_defaultNamespace_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_defaultNamespace_presult__isset {
  _AccumuloProxy_defaultNamespace_presult__isset() : success(false) {}
  bool success :1;
} _AccumuloProxy_defaultNamespace_presult__isset;

class AccumuloProxy_defaultNamespace_presult {
 public:


  virtual ~AccumuloProxy_defaultNamespace_presult() throw();
  std::string* success;

  _AccumuloProxy_defaultNamespace_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_listNamespaces_args__isset {
  _AccumuloProxy_listNamespaces_args__isset() : login(false) {}
  bool login :1;
} _AccumuloProxy_listNamespaces_args__isset;

class AccumuloProxy_listNamespaces_args {
 public:

  AccumuloProxy_listNamespaces_args(const AccumuloProxy_listNamespaces_args&);
  AccumuloProxy_listNamespaces_args& operator=(const AccumuloProxy_listNamespaces_args&);
  AccumuloProxy_listNamespaces_args() : login() {
  }

  virtual ~AccumuloProxy_listNamespaces_args() throw();
  std::string login;

  _AccumuloProxy_listNamespaces_args__isset __isset;

  void __set_login(const std::string& val);

  bool operator == (const AccumuloProxy_listNamespaces_args & rhs) const
  {
    if (!(login == rhs.login))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_listNamespaces_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_listNamespaces_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_listNamespaces_pargs {
 public:


  virtual ~AccumuloProxy_listNamespaces_pargs() throw();
  const std::string* login;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_listNamespaces_result__isset {
  _AccumuloProxy_listNamespaces_result__isset() : success(false), ouch1(false), ouch2(false) {}
  bool success :1;
  bool ouch1 :1;
  bool ouch2 :1;
} _AccumuloProxy_listNamespaces_result__isset;

class AccumuloProxy_listNamespaces_result {
 public:

  AccumuloProxy_listNamespaces_result(const AccumuloProxy_listNamespaces_result&);
  AccumuloProxy_listNamespaces_result& operator=(const AccumuloProxy_listNamespaces_result&);
  AccumuloProxy_listNamespaces_result() {
  }

  virtual ~AccumuloProxy_listNamespaces_result() throw();
  std::vector<std::string>  success;
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;

  _AccumuloProxy_listNamespaces_result__isset __isset;

  void __set_success(const std::vector<std::string> & val);

  void __set_ouch1(const AccumuloException& val);

  void __set_ouch2(const AccumuloSecurityException& val);

  bool operator == (const AccumuloProxy_listNamespaces_result & rhs) const
  {
    if (!(success == rhs.success))
      return false;
    if (!(ouch1 == rhs.ouch1))
      return false;
    if (!(ouch2 == rhs.ouch2))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_listNamespaces_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_listNamespaces_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_listNamespaces_presult__isset {
  _AccumuloProxy_listNamespaces_presult__isset() : success(false), ouch1(false), ouch2(false) {}
  bool success :1;
  bool ouch1 :1;
  bool ouch2 :1;
} _AccumuloProxy_listNamespaces_presult__isset;

class AccumuloProxy_listNamespaces_presult {
 public:


  virtual ~AccumuloProxy_listNamespaces_presult() throw();
  std::vector<std::string> * success;
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;

  _AccumuloProxy_listNamespaces_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_namespaceExists_args__isset {
  _AccumuloProxy_namespaceExists_args__isset() : login(false), namespaceName(false) {}
  bool login :1;
  bool namespaceName :1;
} _AccumuloProxy_namespaceExists_args__isset;

class AccumuloProxy_namespaceExists_args {
 public:

  AccumuloProxy_namespaceExists_args(const AccumuloProxy_namespaceExists_args&);
  AccumuloProxy_namespaceExists_args& operator=(const AccumuloProxy_namespaceExists_args&);
  AccumuloProxy_namespaceExists_args() : login(), namespaceName() {
  }

  virtual ~AccumuloProxy_namespaceExists_args() throw();
  std::string login;
  std::string namespaceName;

  _AccumuloProxy_namespaceExists_args__isset __isset;

  void __set_login(const std::string& val);

  void __set_namespaceName(const std::string& val);

  bool operator == (const AccumuloProxy_namespaceExists_args & rhs) const
  {
    if (!(login == rhs.login))
      return false;
    if (!(namespaceName == rhs.namespaceName))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_namespaceExists_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_namespaceExists_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_namespaceExists_pargs {
 public:


  virtual ~AccumuloProxy_namespaceExists_pargs() throw();
  const std::string* login;
  const std::string* namespaceName;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_namespaceExists_result__isset {
  _AccumuloProxy_namespaceExists_result__isset() : success(false), ouch1(false), ouch2(false) {}
  bool success :1;
  bool ouch1 :1;
  bool ouch2 :1;
} _AccumuloProxy_namespaceExists_result__isset;

class AccumuloProxy_namespaceExists_result {
 public:

  AccumuloProxy_namespaceExists_result(const AccumuloProxy_namespaceExists_result&);
  AccumuloProxy_namespaceExists_result& operator=(const AccumuloProxy_namespaceExists_result&);
  AccumuloProxy_namespaceExists_result() : success(0) {
  }

  virtual ~AccumuloProxy_namespaceExists_result() throw();
  bool success;
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;

  _AccumuloProxy_namespaceExists_result__isset __isset;

  void __set_success(const bool val);

  void __set_ouch1(const AccumuloException& val);

  void __set_ouch2(const AccumuloSecurityException& val);

  bool operator == (const AccumuloProxy_namespaceExists_result & rhs) const
  {
    if (!(success == rhs.success))
      return false;
    if (!(ouch1 == rhs.ouch1))
      return false;
    if (!(ouch2 == rhs.ouch2))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_namespaceExists_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_namespaceExists_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_namespaceExists_presult__isset {
  _AccumuloProxy_namespaceExists_presult__isset() : success(false), ouch1(false), ouch2(false) {}
  bool success :1;
  bool ouch1 :1;
  bool ouch2 :1;
} _AccumuloProxy_namespaceExists_presult__isset;

class AccumuloProxy_namespaceExists_presult {
 public:


  virtual ~AccumuloProxy_namespaceExists_presult() throw();
  bool* success;
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;

  _AccumuloProxy_namespaceExists_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_createNamespace_args__isset {
  _AccumuloProxy_createNamespace_args__isset() : login(false), namespaceName(false) {}
  bool login :1;
  bool namespaceName :1;
} _AccumuloProxy_createNamespace_args__isset;

class AccumuloProxy_createNamespace_args {
 public:

  AccumuloProxy_createNamespace_args(const AccumuloProxy_createNamespace_args&);
  AccumuloProxy_createNamespace_args& operator=(const AccumuloProxy_createNamespace_args&);
  AccumuloProxy_createNamespace_args() : login(), namespaceName() {
  }

  virtual ~AccumuloProxy_createNamespace_args() throw();
  std::string login;
  std::string namespaceName;

  _AccumuloProxy_createNamespace_args__isset __isset;

  void __set_login(const std::string& val);

  void __set_namespaceName(const std::string& val);

  bool operator == (const AccumuloProxy_createNamespace_args & rhs) const
  {
    if (!(login == rhs.login))
      return false;
    if (!(namespaceName == rhs.namespaceName))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_createNamespace_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_createNamespace_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_createNamespace_pargs {
 public:


  virtual ~AccumuloProxy_createNamespace_pargs() throw();
  const std::string* login;
  const std::string* namespaceName;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_createNamespace_result__isset {
  _AccumuloProxy_createNamespace_result__isset() : ouch1(false), ouch2(false), ouch3(false) {}
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_createNamespace_result__isset;

class AccumuloProxy_createNamespace_result {
 public:

  AccumuloProxy_createNamespace_result(const AccumuloProxy_createNamespace_result&);
  AccumuloProxy_createNamespace_result& operator=(const AccumuloProxy_createNamespace_result&);
  AccumuloProxy_createNamespace_result() {
  }

  virtual ~AccumuloProxy_createNamespace_result() throw();
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  NamespaceExistsException ouch3;

  _AccumuloProxy_createNamespace_result__isset __isset;

  void __set_ouch1(const AccumuloException& val);

  void __set_ouch2(const AccumuloSecurityException& val);

  void __set_ouch3(const NamespaceExistsException& val);

  bool operator == (const AccumuloProxy_createNamespace_result & rhs) const
  {
    if (!(ouch1 == rhs.ouch1))
      return false;
    if (!(ouch2 == rhs.ouch2))
      return false;
    if (!(ouch3 == rhs.ouch3))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_createNamespace_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_createNamespace_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_createNamespace_presult__isset {
  _AccumuloProxy_createNamespace_presult__isset() : ouch1(false), ouch2(false), ouch3(false) {}
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_createNamespace_presult__isset;

class AccumuloProxy_createNamespace_presult {
 public:


  virtual ~AccumuloProxy_createNamespace_presult() throw();
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  NamespaceExistsException ouch3;

  _AccumuloProxy_createNamespace_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_deleteNamespace_args__isset {
  _AccumuloProxy_deleteNamespace_args__isset() : login(false), namespaceName(false) {}
  bool login :1;
  bool namespaceName :1;
} _AccumuloProxy_deleteNamespace_args__isset;

class AccumuloProxy_deleteNamespace_args {
 public:

  AccumuloProxy_deleteNamespace_args(const AccumuloProxy_deleteNamespace_args&);
  AccumuloProxy_deleteNamespace_args& operator=(const AccumuloProxy_deleteNamespace_args&);
  AccumuloProxy_deleteNamespace_args() : login(), namespaceName() {
  }

  virtual ~AccumuloProxy_deleteNamespace_args() throw();
  std::string login;
  std::string namespaceName;

  _AccumuloProxy_deleteNamespace_args__isset __isset;

  void __set_login(const std::string& val);

  void __set_namespaceName(const std::string& val);

  bool operator == (const AccumuloProxy_deleteNamespace_args & rhs) const
  {
    if (!(login == rhs.login))
      return false;
    if (!(namespaceName == rhs.namespaceName))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_deleteNamespace_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_deleteNamespace_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_deleteNamespace_pargs {
 public:


  virtual ~AccumuloProxy_deleteNamespace_pargs() throw();
  const std::string* login;
  const std::string* namespaceName;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_deleteNamespace_result__isset {
  _AccumuloProxy_deleteNamespace_result__isset() : ouch1(false), ouch2(false), ouch3(false), ouch4(false) {}
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
  bool ouch4 :1;
} _AccumuloProxy_deleteNamespace_result__isset;

class AccumuloProxy_deleteNamespace_result {
 public:

  AccumuloProxy_deleteNamespace_result(const AccumuloProxy_deleteNamespace_result&);
  AccumuloProxy_deleteNamespace_result& operator=(const AccumuloProxy_deleteNamespace_result&);
  AccumuloProxy_deleteNamespace_result() {
  }

  virtual ~AccumuloProxy_deleteNamespace_result() throw();
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  NamespaceNotFoundException ouch3;
  NamespaceNotEmptyException ouch4;

  _AccumuloProxy_deleteNamespace_result__isset __isset;

  void __set_ouch1(const AccumuloException& val);

  void __set_ouch2(const AccumuloSecurityException& val);

  void __set_ouch3(const NamespaceNotFoundException& val);

  void __set_ouch4(const NamespaceNotEmptyException& val);

  bool operator == (const AccumuloProxy_deleteNamespace_result & rhs) const
  {
    if (!(ouch1 == rhs.ouch1))
      return false;
    if (!(ouch2 == rhs.ouch2))
      return false;
    if (!(ouch3 == rhs.ouch3))
      return false;
    if (!(ouch4 == rhs.ouch4))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_deleteNamespace_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_deleteNamespace_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_deleteNamespace_presult__isset {
  _AccumuloProxy_deleteNamespace_presult__isset() : ouch1(false), ouch2(false), ouch3(false), ouch4(false) {}
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
  bool ouch4 :1;
} _AccumuloProxy_deleteNamespace_presult__isset;

class AccumuloProxy_deleteNamespace_presult {
 public:


  virtual ~AccumuloProxy_deleteNamespace_presult() throw();
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  NamespaceNotFoundException ouch3;
  NamespaceNotEmptyException ouch4;

  _AccumuloProxy_deleteNamespace_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_renameNamespace_args__isset {
  _AccumuloProxy_renameNamespace_args__isset() : login(false), oldNamespaceName(false), newNamespaceName(false) {}
  bool login :1;
  bool oldNamespaceName :1;
  bool newNamespaceName :1;
} _AccumuloProxy_renameNamespace_args__isset;

class AccumuloProxy_renameNamespace_args {
 public:

  AccumuloProxy_renameNamespace_args(const AccumuloProxy_renameNamespace_args&);
  AccumuloProxy_renameNamespace_args& operator=(const AccumuloProxy_renameNamespace_args&);
  AccumuloProxy_renameNamespace_args() : login(), oldNamespaceName(), newNamespaceName() {
  }

  virtual ~AccumuloProxy_renameNamespace_args() throw();
  std::string login;
  std::string oldNamespaceName;
  std::string newNamespaceName;

  _AccumuloProxy_renameNamespace_args__isset __isset;

  void __set_login(const std::string& val);

  void __set_oldNamespaceName(const std::string& val);

  void __set_newNamespaceName(const std::string& val);

  bool operator == (const AccumuloProxy_renameNamespace_args & rhs) const
  {
    if (!(login == rhs.login))
      return false;
    if (!(oldNamespaceName == rhs.oldNamespaceName))
      return false;
    if (!(newNamespaceName == rhs.newNamespaceName))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_renameNamespace_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_renameNamespace_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_renameNamespace_pargs {
 public:


  virtual ~AccumuloProxy_renameNamespace_pargs() throw();
  const std::string* login;
  const std::string* oldNamespaceName;
  const std::string* newNamespaceName;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_renameNamespace_result__isset {
  _AccumuloProxy_renameNamespace_result__isset() : ouch1(false), ouch2(false), ouch3(false), ouch4(false) {}
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
  bool ouch4 :1;
} _AccumuloProxy_renameNamespace_result__isset;

class AccumuloProxy_renameNamespace_result {
 public:

  AccumuloProxy_renameNamespace_result(const AccumuloProxy_renameNamespace_result&);
  AccumuloProxy_renameNamespace_result& operator=(const AccumuloProxy_renameNamespace_result&);
  AccumuloProxy_renameNamespace_result() {
  }

  virtual ~AccumuloProxy_renameNamespace_result() throw();
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  NamespaceNotFoundException ouch3;
  NamespaceExistsException ouch4;

  _AccumuloProxy_renameNamespace_result__isset __isset;

  void __set_ouch1(const AccumuloException& val);

  void __set_ouch2(const AccumuloSecurityException& val);

  void __set_ouch3(const NamespaceNotFoundException& val);

  void __set_ouch4(const NamespaceExistsException& val);

  bool operator == (const AccumuloProxy_renameNamespace_result & rhs) const
  {
    if (!(ouch1 == rhs.ouch1))
      return false;
    if (!(ouch2 == rhs.ouch2))
      return false;
    if (!(ouch3 == rhs.ouch3))
      return false;
    if (!(ouch4 == rhs.ouch4))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_renameNamespace_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_renameNamespace_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_renameNamespace_presult__isset {
  _AccumuloProxy_renameNamespace_presult__isset() : ouch1(false), ouch2(false), ouch3(false), ouch4(false) {}
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
  bool ouch4 :1;
} _AccumuloProxy_renameNamespace_presult__isset;

class AccumuloProxy_renameNamespace_presult {
 public:


  virtual ~AccumuloProxy_renameNamespace_presult() throw();
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  NamespaceNotFoundException ouch3;
  NamespaceExistsException ouch4;

  _AccumuloProxy_renameNamespace_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_setNamespaceProperty_args__isset {
  _AccumuloProxy_setNamespaceProperty_args__isset() : login(false), namespaceName(false), property(false), value(false) {}
  bool login :1;
  bool namespaceName :1;
  bool property :1;
  bool value :1;
} _AccumuloProxy_setNamespaceProperty_args__isset;

class AccumuloProxy_setNamespaceProperty_args {
 public:

  AccumuloProxy_setNamespaceProperty_args(const AccumuloProxy_setNamespaceProperty_args&);
  AccumuloProxy_setNamespaceProperty_args& operator=(const AccumuloProxy_setNamespaceProperty_args&);
  AccumuloProxy_setNamespaceProperty_args() : login(), namespaceName(), property(), value() {
  }

  virtual ~AccumuloProxy_setNamespaceProperty_args() throw();
  std::string login;
  std::string namespaceName;
  std::string property;
  std::string value;

  _AccumuloProxy_setNamespaceProperty_args__isset __isset;

  void __set_login(const std::string& val);

  void __set_namespaceName(const std::string& val);

  void __set_property(const std::string& val);

  void __set_value(const std::string& val);

  bool operator == (const AccumuloProxy_setNamespaceProperty_args & rhs) const
  {
    if (!(login == rhs.login))
      return false;
    if (!(namespaceName == rhs.namespaceName))
      return false;
    if (!(property == rhs.property))
      return false;
    if (!(value == rhs.value))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_setNamespaceProperty_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_setNamespaceProperty_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_setNamespaceProperty_pargs {
 public:


  virtual ~AccumuloProxy_setNamespaceProperty_pargs() throw();
  const std::string* login;
  const std::string* namespaceName;
  const std::string* property;
  const std::string* value;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_setNamespaceProperty_result__isset {
  _AccumuloProxy_setNamespaceProperty_result__isset() : ouch1(false), ouch2(false), ouch3(false) {}
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_setNamespaceProperty_result__isset;

class AccumuloProxy_setNamespaceProperty_result {
 public:

  AccumuloProxy_setNamespaceProperty_result(const AccumuloProxy_setNamespaceProperty_result&);
  AccumuloProxy_setNamespaceProperty_result& operator=(const AccumuloProxy_setNamespaceProperty_result&);
  AccumuloProxy_setNamespaceProperty_result() {
  }

  virtual ~AccumuloProxy_setNamespaceProperty_result() throw();
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  NamespaceNotFoundException ouch3;

  _AccumuloProxy_setNamespaceProperty_result__isset __isset;

  void __set_ouch1(const AccumuloException& val);

  void __set_ouch2(const AccumuloSecurityException& val);

  void __set_ouch3(const NamespaceNotFoundException& val);

  bool operator == (const AccumuloProxy_setNamespaceProperty_result & rhs) const
  {
    if (!(ouch1 == rhs.ouch1))
      return false;
    if (!(ouch2 == rhs.ouch2))
      return false;
    if (!(ouch3 == rhs.ouch3))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_setNamespaceProperty_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_setNamespaceProperty_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_setNamespaceProperty_presult__isset {
  _AccumuloProxy_setNamespaceProperty_presult__isset() : ouch1(false), ouch2(false), ouch3(false) {}
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_setNamespaceProperty_presult__isset;

class AccumuloProxy_setNamespaceProperty_presult {
 public:


  virtual ~AccumuloProxy_setNamespaceProperty_presult() throw();
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  NamespaceNotFoundException ouch3;

  _AccumuloProxy_setNamespaceProperty_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_removeNamespaceProperty_args__isset {
  _AccumuloProxy_removeNamespaceProperty_args__isset() : login(false), namespaceName(false), property(false) {}
  bool login :1;
  bool namespaceName :1;
  bool property :1;
} _AccumuloProxy_removeNamespaceProperty_args__isset;

class AccumuloProxy_removeNamespaceProperty_args {
 public:

  AccumuloProxy_removeNamespaceProperty_args(const AccumuloProxy_removeNamespaceProperty_args&);
  AccumuloProxy_removeNamespaceProperty_args& operator=(const AccumuloProxy_removeNamespaceProperty_args&);
  AccumuloProxy_removeNamespaceProperty_args() : login(), namespaceName(), property() {
  }

  virtual ~AccumuloProxy_removeNamespaceProperty_args() throw();
  std::string login;
  std::string namespaceName;
  std::string property;

  _AccumuloProxy_removeNamespaceProperty_args__isset __isset;

  void __set_login(const std::string& val);

  void __set_namespaceName(const std::string& val);

  void __set_property(const std::string& val);

  bool operator == (const AccumuloProxy_removeNamespaceProperty_args & rhs) const
  {
    if (!(login == rhs.login))
      return false;
    if (!(namespaceName == rhs.namespaceName))
      return false;
    if (!(property == rhs.property))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_removeNamespaceProperty_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_removeNamespaceProperty_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_removeNamespaceProperty_pargs {
 public:


  virtual ~AccumuloProxy_removeNamespaceProperty_pargs() throw();
  const std::string* login;
  const std::string* namespaceName;
  const std::string* property;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_removeNamespaceProperty_result__isset {
  _AccumuloProxy_removeNamespaceProperty_result__isset() : ouch1(false), ouch2(false), ouch3(false) {}
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_removeNamespaceProperty_result__isset;

class AccumuloProxy_removeNamespaceProperty_result {
 public:

  AccumuloProxy_removeNamespaceProperty_result(const AccumuloProxy_removeNamespaceProperty_result&);
  AccumuloProxy_removeNamespaceProperty_result& operator=(const AccumuloProxy_removeNamespaceProperty_result&);
  AccumuloProxy_removeNamespaceProperty_result() {
  }

  virtual ~AccumuloProxy_removeNamespaceProperty_result() throw();
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  NamespaceNotFoundException ouch3;

  _AccumuloProxy_removeNamespaceProperty_result__isset __isset;

  void __set_ouch1(const AccumuloException& val);

  void __set_ouch2(const AccumuloSecurityException& val);

  void __set_ouch3(const NamespaceNotFoundException& val);

  bool operator == (const AccumuloProxy_removeNamespaceProperty_result & rhs) const
  {
    if (!(ouch1 == rhs.ouch1))
      return false;
    if (!(ouch2 == rhs.ouch2))
      return false;
    if (!(ouch3 == rhs.ouch3))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_removeNamespaceProperty_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_removeNamespaceProperty_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_removeNamespaceProperty_presult__isset {
  _AccumuloProxy_removeNamespaceProperty_presult__isset() : ouch1(false), ouch2(false), ouch3(false) {}
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_removeNamespaceProperty_presult__isset;

class AccumuloProxy_removeNamespaceProperty_presult {
 public:


  virtual ~AccumuloProxy_removeNamespaceProperty_presult() throw();
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  NamespaceNotFoundException ouch3;

  _AccumuloProxy_removeNamespaceProperty_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_getNamespaceProperties_args__isset {
  _AccumuloProxy_getNamespaceProperties_args__isset() : login(false), namespaceName(false) {}
  bool login :1;
  bool namespaceName :1;
} _AccumuloProxy_getNamespaceProperties_args__isset;

class AccumuloProxy_getNamespaceProperties_args {
 public:

  AccumuloProxy_getNamespaceProperties_args(const AccumuloProxy_getNamespaceProperties_args&);
  AccumuloProxy_getNamespaceProperties_args& operator=(const AccumuloProxy_getNamespaceProperties_args&);
  AccumuloProxy_getNamespaceProperties_args() : login(), namespaceName() {
  }

  virtual ~AccumuloProxy_getNamespaceProperties_args() throw();
  std::string login;
  std::string namespaceName;

  _AccumuloProxy_getNamespaceProperties_args__isset __isset;

  void __set_login(const std::string& val);

  void __set_namespaceName(const std::string& val);

  bool operator == (const AccumuloProxy_getNamespaceProperties_args & rhs) const
  {
    if (!(login == rhs.login))
      return false;
    if (!(namespaceName == rhs.namespaceName))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_getNamespaceProperties_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_getNamespaceProperties_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_getNamespaceProperties_pargs {
 public:


  virtual ~AccumuloProxy_getNamespaceProperties_pargs() throw();
  const std::string* login;
  const std::string* namespaceName;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_getNamespaceProperties_result__isset {
  _AccumuloProxy_getNamespaceProperties_result__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
  bool success :1;
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_getNamespaceProperties_result__isset;

class AccumuloProxy_getNamespaceProperties_result {
 public:

  AccumuloProxy_getNamespaceProperties_result(const AccumuloProxy_getNamespaceProperties_result&);
  AccumuloProxy_getNamespaceProperties_result& operator=(const AccumuloProxy_getNamespaceProperties_result&);
  AccumuloProxy_getNamespaceProperties_result() {
  }

  virtual ~AccumuloProxy_getNamespaceProperties_result() throw();
  std::map<std::string, std::string>  success;
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  NamespaceNotFoundException ouch3;

  _AccumuloProxy_getNamespaceProperties_result__isset __isset;

  void __set_success(const std::map<std::string, std::string> & val);

  void __set_ouch1(const AccumuloException& val);

  void __set_ouch2(const AccumuloSecurityException& val);

  void __set_ouch3(const NamespaceNotFoundException& val);

  bool operator == (const AccumuloProxy_getNamespaceProperties_result & rhs) const
  {
    if (!(success == rhs.success))
      return false;
    if (!(ouch1 == rhs.ouch1))
      return false;
    if (!(ouch2 == rhs.ouch2))
      return false;
    if (!(ouch3 == rhs.ouch3))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_getNamespaceProperties_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_getNamespaceProperties_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_getNamespaceProperties_presult__isset {
  _AccumuloProxy_getNamespaceProperties_presult__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
  bool success :1;
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_getNamespaceProperties_presult__isset;

class AccumuloProxy_getNamespaceProperties_presult {
 public:


  virtual ~AccumuloProxy_getNamespaceProperties_presult() throw();
  std::map<std::string, std::string> * success;
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  NamespaceNotFoundException ouch3;

  _AccumuloProxy_getNamespaceProperties_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_namespaceIdMap_args__isset {
  _AccumuloProxy_namespaceIdMap_args__isset() : login(false) {}
  bool login :1;
} _AccumuloProxy_namespaceIdMap_args__isset;

class AccumuloProxy_namespaceIdMap_args {
 public:

  AccumuloProxy_namespaceIdMap_args(const AccumuloProxy_namespaceIdMap_args&);
  AccumuloProxy_namespaceIdMap_args& operator=(const AccumuloProxy_namespaceIdMap_args&);
  AccumuloProxy_namespaceIdMap_args() : login() {
  }

  virtual ~AccumuloProxy_namespaceIdMap_args() throw();
  std::string login;

  _AccumuloProxy_namespaceIdMap_args__isset __isset;

  void __set_login(const std::string& val);

  bool operator == (const AccumuloProxy_namespaceIdMap_args & rhs) const
  {
    if (!(login == rhs.login))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_namespaceIdMap_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_namespaceIdMap_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_namespaceIdMap_pargs {
 public:


  virtual ~AccumuloProxy_namespaceIdMap_pargs() throw();
  const std::string* login;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_namespaceIdMap_result__isset {
  _AccumuloProxy_namespaceIdMap_result__isset() : success(false), ouch1(false), ouch2(false) {}
  bool success :1;
  bool ouch1 :1;
  bool ouch2 :1;
} _AccumuloProxy_namespaceIdMap_result__isset;

class AccumuloProxy_namespaceIdMap_result {
 public:

  AccumuloProxy_namespaceIdMap_result(const AccumuloProxy_namespaceIdMap_result&);
  AccumuloProxy_namespaceIdMap_result& operator=(const AccumuloProxy_namespaceIdMap_result&);
  AccumuloProxy_namespaceIdMap_result() {
  }

  virtual ~AccumuloProxy_namespaceIdMap_result() throw();
  std::map<std::string, std::string>  success;
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;

  _AccumuloProxy_namespaceIdMap_result__isset __isset;

  void __set_success(const std::map<std::string, std::string> & val);

  void __set_ouch1(const AccumuloException& val);

  void __set_ouch2(const AccumuloSecurityException& val);

  bool operator == (const AccumuloProxy_namespaceIdMap_result & rhs) const
  {
    if (!(success == rhs.success))
      return false;
    if (!(ouch1 == rhs.ouch1))
      return false;
    if (!(ouch2 == rhs.ouch2))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_namespaceIdMap_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_namespaceIdMap_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_namespaceIdMap_presult__isset {
  _AccumuloProxy_namespaceIdMap_presult__isset() : success(false), ouch1(false), ouch2(false) {}
  bool success :1;
  bool ouch1 :1;
  bool ouch2 :1;
} _AccumuloProxy_namespaceIdMap_presult__isset;

class AccumuloProxy_namespaceIdMap_presult {
 public:


  virtual ~AccumuloProxy_namespaceIdMap_presult() throw();
  std::map<std::string, std::string> * success;
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;

  _AccumuloProxy_namespaceIdMap_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_attachNamespaceIterator_args__isset {
  _AccumuloProxy_attachNamespaceIterator_args__isset() : login(false), namespaceName(false), setting(false), scopes(false) {}
  bool login :1;
  bool namespaceName :1;
  bool setting :1;
  bool scopes :1;
} _AccumuloProxy_attachNamespaceIterator_args__isset;

class AccumuloProxy_attachNamespaceIterator_args {
 public:

  AccumuloProxy_attachNamespaceIterator_args(const AccumuloProxy_attachNamespaceIterator_args&);
  AccumuloProxy_attachNamespaceIterator_args& operator=(const AccumuloProxy_attachNamespaceIterator_args&);
  AccumuloProxy_attachNamespaceIterator_args() : login(), namespaceName() {
  }

  virtual ~AccumuloProxy_attachNamespaceIterator_args() throw();
  std::string login;
  std::string namespaceName;
  IteratorSetting setting;
  std::set<IteratorScope::type>  scopes;

  _AccumuloProxy_attachNamespaceIterator_args__isset __isset;

  void __set_login(const std::string& val);

  void __set_namespaceName(const std::string& val);

  void __set_setting(const IteratorSetting& val);

  void __set_scopes(const std::set<IteratorScope::type> & val);

  bool operator == (const AccumuloProxy_attachNamespaceIterator_args & rhs) const
  {
    if (!(login == rhs.login))
      return false;
    if (!(namespaceName == rhs.namespaceName))
      return false;
    if (!(setting == rhs.setting))
      return false;
    if (!(scopes == rhs.scopes))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_attachNamespaceIterator_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_attachNamespaceIterator_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_attachNamespaceIterator_pargs {
 public:


  virtual ~AccumuloProxy_attachNamespaceIterator_pargs() throw();
  const std::string* login;
  const std::string* namespaceName;
  const IteratorSetting* setting;
  const std::set<IteratorScope::type> * scopes;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_attachNamespaceIterator_result__isset {
  _AccumuloProxy_attachNamespaceIterator_result__isset() : ouch1(false), ouch2(false), ouch3(false) {}
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_attachNamespaceIterator_result__isset;

class AccumuloProxy_attachNamespaceIterator_result {
 public:

  AccumuloProxy_attachNamespaceIterator_result(const AccumuloProxy_attachNamespaceIterator_result&);
  AccumuloProxy_attachNamespaceIterator_result& operator=(const AccumuloProxy_attachNamespaceIterator_result&);
  AccumuloProxy_attachNamespaceIterator_result() {
  }

  virtual ~AccumuloProxy_attachNamespaceIterator_result() throw();
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  NamespaceNotFoundException ouch3;

  _AccumuloProxy_attachNamespaceIterator_result__isset __isset;

  void __set_ouch1(const AccumuloException& val);

  void __set_ouch2(const AccumuloSecurityException& val);

  void __set_ouch3(const NamespaceNotFoundException& val);

  bool operator == (const AccumuloProxy_attachNamespaceIterator_result & rhs) const
  {
    if (!(ouch1 == rhs.ouch1))
      return false;
    if (!(ouch2 == rhs.ouch2))
      return false;
    if (!(ouch3 == rhs.ouch3))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_attachNamespaceIterator_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_attachNamespaceIterator_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_attachNamespaceIterator_presult__isset {
  _AccumuloProxy_attachNamespaceIterator_presult__isset() : ouch1(false), ouch2(false), ouch3(false) {}
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_attachNamespaceIterator_presult__isset;

class AccumuloProxy_attachNamespaceIterator_presult {
 public:


  virtual ~AccumuloProxy_attachNamespaceIterator_presult() throw();
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  NamespaceNotFoundException ouch3;

  _AccumuloProxy_attachNamespaceIterator_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_removeNamespaceIterator_args__isset {
  _AccumuloProxy_removeNamespaceIterator_args__isset() : login(false), namespaceName(false), name(false), scopes(false) {}
  bool login :1;
  bool namespaceName :1;
  bool name :1;
  bool scopes :1;
} _AccumuloProxy_removeNamespaceIterator_args__isset;

class AccumuloProxy_removeNamespaceIterator_args {
 public:

  AccumuloProxy_removeNamespaceIterator_args(const AccumuloProxy_removeNamespaceIterator_args&);
  AccumuloProxy_removeNamespaceIterator_args& operator=(const AccumuloProxy_removeNamespaceIterator_args&);
  AccumuloProxy_removeNamespaceIterator_args() : login(), namespaceName(), name() {
  }

  virtual ~AccumuloProxy_removeNamespaceIterator_args() throw();
  std::string login;
  std::string namespaceName;
  std::string name;
  std::set<IteratorScope::type>  scopes;

  _AccumuloProxy_removeNamespaceIterator_args__isset __isset;

  void __set_login(const std::string& val);

  void __set_namespaceName(const std::string& val);

  void __set_name(const std::string& val);

  void __set_scopes(const std::set<IteratorScope::type> & val);

  bool operator == (const AccumuloProxy_removeNamespaceIterator_args & rhs) const
  {
    if (!(login == rhs.login))
      return false;
    if (!(namespaceName == rhs.namespaceName))
      return false;
    if (!(name == rhs.name))
      return false;
    if (!(scopes == rhs.scopes))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_removeNamespaceIterator_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_removeNamespaceIterator_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_removeNamespaceIterator_pargs {
 public:


  virtual ~AccumuloProxy_removeNamespaceIterator_pargs() throw();
  const std::string* login;
  const std::string* namespaceName;
  const std::string* name;
  const std::set<IteratorScope::type> * scopes;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_removeNamespaceIterator_result__isset {
  _AccumuloProxy_removeNamespaceIterator_result__isset() : ouch1(false), ouch2(false), ouch3(false) {}
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_removeNamespaceIterator_result__isset;

class AccumuloProxy_removeNamespaceIterator_result {
 public:

  AccumuloProxy_removeNamespaceIterator_result(const AccumuloProxy_removeNamespaceIterator_result&);
  AccumuloProxy_removeNamespaceIterator_result& operator=(const AccumuloProxy_removeNamespaceIterator_result&);
  AccumuloProxy_removeNamespaceIterator_result() {
  }

  virtual ~AccumuloProxy_removeNamespaceIterator_result() throw();
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  NamespaceNotFoundException ouch3;

  _AccumuloProxy_removeNamespaceIterator_result__isset __isset;

  void __set_ouch1(const AccumuloException& val);

  void __set_ouch2(const AccumuloSecurityException& val);

  void __set_ouch3(const NamespaceNotFoundException& val);

  bool operator == (const AccumuloProxy_removeNamespaceIterator_result & rhs) const
  {
    if (!(ouch1 == rhs.ouch1))
      return false;
    if (!(ouch2 == rhs.ouch2))
      return false;
    if (!(ouch3 == rhs.ouch3))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_removeNamespaceIterator_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_removeNamespaceIterator_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_removeNamespaceIterator_presult__isset {
  _AccumuloProxy_removeNamespaceIterator_presult__isset() : ouch1(false), ouch2(false), ouch3(false) {}
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_removeNamespaceIterator_presult__isset;

class AccumuloProxy_removeNamespaceIterator_presult {
 public:


  virtual ~AccumuloProxy_removeNamespaceIterator_presult() throw();
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  NamespaceNotFoundException ouch3;

  _AccumuloProxy_removeNamespaceIterator_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_getNamespaceIteratorSetting_args__isset {
  _AccumuloProxy_getNamespaceIteratorSetting_args__isset() : login(false), namespaceName(false), name(false), scope(false) {}
  bool login :1;
  bool namespaceName :1;
  bool name :1;
  bool scope :1;
} _AccumuloProxy_getNamespaceIteratorSetting_args__isset;

class AccumuloProxy_getNamespaceIteratorSetting_args {
 public:

  AccumuloProxy_getNamespaceIteratorSetting_args(const AccumuloProxy_getNamespaceIteratorSetting_args&);
  AccumuloProxy_getNamespaceIteratorSetting_args& operator=(const AccumuloProxy_getNamespaceIteratorSetting_args&);
  AccumuloProxy_getNamespaceIteratorSetting_args() : login(), namespaceName(), name(), scope((IteratorScope::type)0) {
  }

  virtual ~AccumuloProxy_getNamespaceIteratorSetting_args() throw();
  std::string login;
  std::string namespaceName;
  std::string name;
  IteratorScope::type scope;

  _AccumuloProxy_getNamespaceIteratorSetting_args__isset __isset;

  void __set_login(const std::string& val);

  void __set_namespaceName(const std::string& val);

  void __set_name(const std::string& val);

  void __set_scope(const IteratorScope::type val);

  bool operator == (const AccumuloProxy_getNamespaceIteratorSetting_args & rhs) const
  {
    if (!(login == rhs.login))
      return false;
    if (!(namespaceName == rhs.namespaceName))
      return false;
    if (!(name == rhs.name))
      return false;
    if (!(scope == rhs.scope))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_getNamespaceIteratorSetting_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_getNamespaceIteratorSetting_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_getNamespaceIteratorSetting_pargs {
 public:


  virtual ~AccumuloProxy_getNamespaceIteratorSetting_pargs() throw();
  const std::string* login;
  const std::string* namespaceName;
  const std::string* name;
  const IteratorScope::type* scope;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_getNamespaceIteratorSetting_result__isset {
  _AccumuloProxy_getNamespaceIteratorSetting_result__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
  bool success :1;
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_getNamespaceIteratorSetting_result__isset;

class AccumuloProxy_getNamespaceIteratorSetting_result {
 public:

  AccumuloProxy_getNamespaceIteratorSetting_result(const AccumuloProxy_getNamespaceIteratorSetting_result&);
  AccumuloProxy_getNamespaceIteratorSetting_result& operator=(const AccumuloProxy_getNamespaceIteratorSetting_result&);
  AccumuloProxy_getNamespaceIteratorSetting_result() {
  }

  virtual ~AccumuloProxy_getNamespaceIteratorSetting_result() throw();
  IteratorSetting success;
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  NamespaceNotFoundException ouch3;

  _AccumuloProxy_getNamespaceIteratorSetting_result__isset __isset;

  void __set_success(const IteratorSetting& val);

  void __set_ouch1(const AccumuloException& val);

  void __set_ouch2(const AccumuloSecurityException& val);

  void __set_ouch3(const NamespaceNotFoundException& val);

  bool operator == (const AccumuloProxy_getNamespaceIteratorSetting_result & rhs) const
  {
    if (!(success == rhs.success))
      return false;
    if (!(ouch1 == rhs.ouch1))
      return false;
    if (!(ouch2 == rhs.ouch2))
      return false;
    if (!(ouch3 == rhs.ouch3))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_getNamespaceIteratorSetting_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_getNamespaceIteratorSetting_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_getNamespaceIteratorSetting_presult__isset {
  _AccumuloProxy_getNamespaceIteratorSetting_presult__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
  bool success :1;
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_getNamespaceIteratorSetting_presult__isset;

class AccumuloProxy_getNamespaceIteratorSetting_presult {
 public:


  virtual ~AccumuloProxy_getNamespaceIteratorSetting_presult() throw();
  IteratorSetting* success;
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  NamespaceNotFoundException ouch3;

  _AccumuloProxy_getNamespaceIteratorSetting_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_listNamespaceIterators_args__isset {
  _AccumuloProxy_listNamespaceIterators_args__isset() : login(false), namespaceName(false) {}
  bool login :1;
  bool namespaceName :1;
} _AccumuloProxy_listNamespaceIterators_args__isset;

class AccumuloProxy_listNamespaceIterators_args {
 public:

  AccumuloProxy_listNamespaceIterators_args(const AccumuloProxy_listNamespaceIterators_args&);
  AccumuloProxy_listNamespaceIterators_args& operator=(const AccumuloProxy_listNamespaceIterators_args&);
  AccumuloProxy_listNamespaceIterators_args() : login(), namespaceName() {
  }

  virtual ~AccumuloProxy_listNamespaceIterators_args() throw();
  std::string login;
  std::string namespaceName;

  _AccumuloProxy_listNamespaceIterators_args__isset __isset;

  void __set_login(const std::string& val);

  void __set_namespaceName(const std::string& val);

  bool operator == (const AccumuloProxy_listNamespaceIterators_args & rhs) const
  {
    if (!(login == rhs.login))
      return false;
    if (!(namespaceName == rhs.namespaceName))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_listNamespaceIterators_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_listNamespaceIterators_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_listNamespaceIterators_pargs {
 public:


  virtual ~AccumuloProxy_listNamespaceIterators_pargs() throw();
  const std::string* login;
  const std::string* namespaceName;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_listNamespaceIterators_result__isset {
  _AccumuloProxy_listNamespaceIterators_result__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
  bool success :1;
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_listNamespaceIterators_result__isset;

class AccumuloProxy_listNamespaceIterators_result {
 public:

  AccumuloProxy_listNamespaceIterators_result(const AccumuloProxy_listNamespaceIterators_result&);
  AccumuloProxy_listNamespaceIterators_result& operator=(const AccumuloProxy_listNamespaceIterators_result&);
  AccumuloProxy_listNamespaceIterators_result() {
  }

  virtual ~AccumuloProxy_listNamespaceIterators_result() throw();
  std::map<std::string, std::set<IteratorScope::type> >  success;
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  NamespaceNotFoundException ouch3;

  _AccumuloProxy_listNamespaceIterators_result__isset __isset;

  void __set_success(const std::map<std::string, std::set<IteratorScope::type> > & val);

  void __set_ouch1(const AccumuloException& val);

  void __set_ouch2(const AccumuloSecurityException& val);

  void __set_ouch3(const NamespaceNotFoundException& val);

  bool operator == (const AccumuloProxy_listNamespaceIterators_result & rhs) const
  {
    if (!(success == rhs.success))
      return false;
    if (!(ouch1 == rhs.ouch1))
      return false;
    if (!(ouch2 == rhs.ouch2))
      return false;
    if (!(ouch3 == rhs.ouch3))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_listNamespaceIterators_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_listNamespaceIterators_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_listNamespaceIterators_presult__isset {
  _AccumuloProxy_listNamespaceIterators_presult__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
  bool success :1;
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_listNamespaceIterators_presult__isset;

class AccumuloProxy_listNamespaceIterators_presult {
 public:


  virtual ~AccumuloProxy_listNamespaceIterators_presult() throw();
  std::map<std::string, std::set<IteratorScope::type> > * success;
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  NamespaceNotFoundException ouch3;

  _AccumuloProxy_listNamespaceIterators_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_checkNamespaceIteratorConflicts_args__isset {
  _AccumuloProxy_checkNamespaceIteratorConflicts_args__isset() : login(false), namespaceName(false), setting(false), scopes(false) {}
  bool login :1;
  bool namespaceName :1;
  bool setting :1;
  bool scopes :1;
} _AccumuloProxy_checkNamespaceIteratorConflicts_args__isset;

class AccumuloProxy_checkNamespaceIteratorConflicts_args {
 public:

  AccumuloProxy_checkNamespaceIteratorConflicts_args(const AccumuloProxy_checkNamespaceIteratorConflicts_args&);
  AccumuloProxy_checkNamespaceIteratorConflicts_args& operator=(const AccumuloProxy_checkNamespaceIteratorConflicts_args&);
  AccumuloProxy_checkNamespaceIteratorConflicts_args() : login(), namespaceName() {
  }

  virtual ~AccumuloProxy_checkNamespaceIteratorConflicts_args() throw();
  std::string login;
  std::string namespaceName;
  IteratorSetting setting;
  std::set<IteratorScope::type>  scopes;

  _AccumuloProxy_checkNamespaceIteratorConflicts_args__isset __isset;

  void __set_login(const std::string& val);

  void __set_namespaceName(const std::string& val);

  void __set_setting(const IteratorSetting& val);

  void __set_scopes(const std::set<IteratorScope::type> & val);

  bool operator == (const AccumuloProxy_checkNamespaceIteratorConflicts_args & rhs) const
  {
    if (!(login == rhs.login))
      return false;
    if (!(namespaceName == rhs.namespaceName))
      return false;
    if (!(setting == rhs.setting))
      return false;
    if (!(scopes == rhs.scopes))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_checkNamespaceIteratorConflicts_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_checkNamespaceIteratorConflicts_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_checkNamespaceIteratorConflicts_pargs {
 public:


  virtual ~AccumuloProxy_checkNamespaceIteratorConflicts_pargs() throw();
  const std::string* login;
  const std::string* namespaceName;
  const IteratorSetting* setting;
  const std::set<IteratorScope::type> * scopes;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_checkNamespaceIteratorConflicts_result__isset {
  _AccumuloProxy_checkNamespaceIteratorConflicts_result__isset() : ouch1(false), ouch2(false), ouch3(false) {}
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_checkNamespaceIteratorConflicts_result__isset;

class AccumuloProxy_checkNamespaceIteratorConflicts_result {
 public:

  AccumuloProxy_checkNamespaceIteratorConflicts_result(const AccumuloProxy_checkNamespaceIteratorConflicts_result&);
  AccumuloProxy_checkNamespaceIteratorConflicts_result& operator=(const AccumuloProxy_checkNamespaceIteratorConflicts_result&);
  AccumuloProxy_checkNamespaceIteratorConflicts_result() {
  }

  virtual ~AccumuloProxy_checkNamespaceIteratorConflicts_result() throw();
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  NamespaceNotFoundException ouch3;

  _AccumuloProxy_checkNamespaceIteratorConflicts_result__isset __isset;

  void __set_ouch1(const AccumuloException& val);

  void __set_ouch2(const AccumuloSecurityException& val);

  void __set_ouch3(const NamespaceNotFoundException& val);

  bool operator == (const AccumuloProxy_checkNamespaceIteratorConflicts_result & rhs) const
  {
    if (!(ouch1 == rhs.ouch1))
      return false;
    if (!(ouch2 == rhs.ouch2))
      return false;
    if (!(ouch3 == rhs.ouch3))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_checkNamespaceIteratorConflicts_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_checkNamespaceIteratorConflicts_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_checkNamespaceIteratorConflicts_presult__isset {
  _AccumuloProxy_checkNamespaceIteratorConflicts_presult__isset() : ouch1(false), ouch2(false), ouch3(false) {}
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_checkNamespaceIteratorConflicts_presult__isset;

class AccumuloProxy_checkNamespaceIteratorConflicts_presult {
 public:


  virtual ~AccumuloProxy_checkNamespaceIteratorConflicts_presult() throw();
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  NamespaceNotFoundException ouch3;

  _AccumuloProxy_checkNamespaceIteratorConflicts_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_addNamespaceConstraint_args__isset {
  _AccumuloProxy_addNamespaceConstraint_args__isset() : login(false), namespaceName(false), constraintClassName(false) {}
  bool login :1;
  bool namespaceName :1;
  bool constraintClassName :1;
} _AccumuloProxy_addNamespaceConstraint_args__isset;

class AccumuloProxy_addNamespaceConstraint_args {
 public:

  AccumuloProxy_addNamespaceConstraint_args(const AccumuloProxy_addNamespaceConstraint_args&);
  AccumuloProxy_addNamespaceConstraint_args& operator=(const AccumuloProxy_addNamespaceConstraint_args&);
  AccumuloProxy_addNamespaceConstraint_args() : login(), namespaceName(), constraintClassName() {
  }

  virtual ~AccumuloProxy_addNamespaceConstraint_args() throw();
  std::string login;
  std::string namespaceName;
  std::string constraintClassName;

  _AccumuloProxy_addNamespaceConstraint_args__isset __isset;

  void __set_login(const std::string& val);

  void __set_namespaceName(const std::string& val);

  void __set_constraintClassName(const std::string& val);

  bool operator == (const AccumuloProxy_addNamespaceConstraint_args & rhs) const
  {
    if (!(login == rhs.login))
      return false;
    if (!(namespaceName == rhs.namespaceName))
      return false;
    if (!(constraintClassName == rhs.constraintClassName))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_addNamespaceConstraint_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_addNamespaceConstraint_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_addNamespaceConstraint_pargs {
 public:


  virtual ~AccumuloProxy_addNamespaceConstraint_pargs() throw();
  const std::string* login;
  const std::string* namespaceName;
  const std::string* constraintClassName;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_addNamespaceConstraint_result__isset {
  _AccumuloProxy_addNamespaceConstraint_result__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
  bool success :1;
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_addNamespaceConstraint_result__isset;

class AccumuloProxy_addNamespaceConstraint_result {
 public:

  AccumuloProxy_addNamespaceConstraint_result(const AccumuloProxy_addNamespaceConstraint_result&);
  AccumuloProxy_addNamespaceConstraint_result& operator=(const AccumuloProxy_addNamespaceConstraint_result&);
  AccumuloProxy_addNamespaceConstraint_result() : success(0) {
  }

  virtual ~AccumuloProxy_addNamespaceConstraint_result() throw();
  int32_t success;
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  NamespaceNotFoundException ouch3;

  _AccumuloProxy_addNamespaceConstraint_result__isset __isset;

  void __set_success(const int32_t val);

  void __set_ouch1(const AccumuloException& val);

  void __set_ouch2(const AccumuloSecurityException& val);

  void __set_ouch3(const NamespaceNotFoundException& val);

  bool operator == (const AccumuloProxy_addNamespaceConstraint_result & rhs) const
  {
    if (!(success == rhs.success))
      return false;
    if (!(ouch1 == rhs.ouch1))
      return false;
    if (!(ouch2 == rhs.ouch2))
      return false;
    if (!(ouch3 == rhs.ouch3))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_addNamespaceConstraint_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_addNamespaceConstraint_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_addNamespaceConstraint_presult__isset {
  _AccumuloProxy_addNamespaceConstraint_presult__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
  bool success :1;
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_addNamespaceConstraint_presult__isset;

class AccumuloProxy_addNamespaceConstraint_presult {
 public:


  virtual ~AccumuloProxy_addNamespaceConstraint_presult() throw();
  int32_t* success;
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  NamespaceNotFoundException ouch3;

  _AccumuloProxy_addNamespaceConstraint_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_removeNamespaceConstraint_args__isset {
  _AccumuloProxy_removeNamespaceConstraint_args__isset() : login(false), namespaceName(false), id(false) {}
  bool login :1;
  bool namespaceName :1;
  bool id :1;
} _AccumuloProxy_removeNamespaceConstraint_args__isset;

class AccumuloProxy_removeNamespaceConstraint_args {
 public:

  AccumuloProxy_removeNamespaceConstraint_args(const AccumuloProxy_removeNamespaceConstraint_args&);
  AccumuloProxy_removeNamespaceConstraint_args& operator=(const AccumuloProxy_removeNamespaceConstraint_args&);
  AccumuloProxy_removeNamespaceConstraint_args() : login(), namespaceName(), id(0) {
  }

  virtual ~AccumuloProxy_removeNamespaceConstraint_args() throw();
  std::string login;
  std::string namespaceName;
  int32_t id;

  _AccumuloProxy_removeNamespaceConstraint_args__isset __isset;

  void __set_login(const std::string& val);

  void __set_namespaceName(const std::string& val);

  void __set_id(const int32_t val);

  bool operator == (const AccumuloProxy_removeNamespaceConstraint_args & rhs) const
  {
    if (!(login == rhs.login))
      return false;
    if (!(namespaceName == rhs.namespaceName))
      return false;
    if (!(id == rhs.id))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_removeNamespaceConstraint_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_removeNamespaceConstraint_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_removeNamespaceConstraint_pargs {
 public:


  virtual ~AccumuloProxy_removeNamespaceConstraint_pargs() throw();
  const std::string* login;
  const std::string* namespaceName;
  const int32_t* id;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_removeNamespaceConstraint_result__isset {
  _AccumuloProxy_removeNamespaceConstraint_result__isset() : ouch1(false), ouch2(false), ouch3(false) {}
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_removeNamespaceConstraint_result__isset;

class AccumuloProxy_removeNamespaceConstraint_result {
 public:

  AccumuloProxy_removeNamespaceConstraint_result(const AccumuloProxy_removeNamespaceConstraint_result&);
  AccumuloProxy_removeNamespaceConstraint_result& operator=(const AccumuloProxy_removeNamespaceConstraint_result&);
  AccumuloProxy_removeNamespaceConstraint_result() {
  }

  virtual ~AccumuloProxy_removeNamespaceConstraint_result() throw();
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  NamespaceNotFoundException ouch3;

  _AccumuloProxy_removeNamespaceConstraint_result__isset __isset;

  void __set_ouch1(const AccumuloException& val);

  void __set_ouch2(const AccumuloSecurityException& val);

  void __set_ouch3(const NamespaceNotFoundException& val);

  bool operator == (const AccumuloProxy_removeNamespaceConstraint_result & rhs) const
  {
    if (!(ouch1 == rhs.ouch1))
      return false;
    if (!(ouch2 == rhs.ouch2))
      return false;
    if (!(ouch3 == rhs.ouch3))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_removeNamespaceConstraint_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_removeNamespaceConstraint_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_removeNamespaceConstraint_presult__isset {
  _AccumuloProxy_removeNamespaceConstraint_presult__isset() : ouch1(false), ouch2(false), ouch3(false) {}
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_removeNamespaceConstraint_presult__isset;

class AccumuloProxy_removeNamespaceConstraint_presult {
 public:


  virtual ~AccumuloProxy_removeNamespaceConstraint_presult() throw();
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  NamespaceNotFoundException ouch3;

  _AccumuloProxy_removeNamespaceConstraint_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_listNamespaceConstraints_args__isset {
  _AccumuloProxy_listNamespaceConstraints_args__isset() : login(false), namespaceName(false) {}
  bool login :1;
  bool namespaceName :1;
} _AccumuloProxy_listNamespaceConstraints_args__isset;

class AccumuloProxy_listNamespaceConstraints_args {
 public:

  AccumuloProxy_listNamespaceConstraints_args(const AccumuloProxy_listNamespaceConstraints_args&);
  AccumuloProxy_listNamespaceConstraints_args& operator=(const AccumuloProxy_listNamespaceConstraints_args&);
  AccumuloProxy_listNamespaceConstraints_args() : login(), namespaceName() {
  }

  virtual ~AccumuloProxy_listNamespaceConstraints_args() throw();
  std::string login;
  std::string namespaceName;

  _AccumuloProxy_listNamespaceConstraints_args__isset __isset;

  void __set_login(const std::string& val);

  void __set_namespaceName(const std::string& val);

  bool operator == (const AccumuloProxy_listNamespaceConstraints_args & rhs) const
  {
    if (!(login == rhs.login))
      return false;
    if (!(namespaceName == rhs.namespaceName))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_listNamespaceConstraints_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_listNamespaceConstraints_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_listNamespaceConstraints_pargs {
 public:


  virtual ~AccumuloProxy_listNamespaceConstraints_pargs() throw();
  const std::string* login;
  const std::string* namespaceName;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_listNamespaceConstraints_result__isset {
  _AccumuloProxy_listNamespaceConstraints_result__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
  bool success :1;
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_listNamespaceConstraints_result__isset;

class AccumuloProxy_listNamespaceConstraints_result {
 public:

  AccumuloProxy_listNamespaceConstraints_result(const AccumuloProxy_listNamespaceConstraints_result&);
  AccumuloProxy_listNamespaceConstraints_result& operator=(const AccumuloProxy_listNamespaceConstraints_result&);
  AccumuloProxy_listNamespaceConstraints_result() {
  }

  virtual ~AccumuloProxy_listNamespaceConstraints_result() throw();
  std::map<std::string, int32_t>  success;
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  NamespaceNotFoundException ouch3;

  _AccumuloProxy_listNamespaceConstraints_result__isset __isset;

  void __set_success(const std::map<std::string, int32_t> & val);

  void __set_ouch1(const AccumuloException& val);

  void __set_ouch2(const AccumuloSecurityException& val);

  void __set_ouch3(const NamespaceNotFoundException& val);

  bool operator == (const AccumuloProxy_listNamespaceConstraints_result & rhs) const
  {
    if (!(success == rhs.success))
      return false;
    if (!(ouch1 == rhs.ouch1))
      return false;
    if (!(ouch2 == rhs.ouch2))
      return false;
    if (!(ouch3 == rhs.ouch3))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_listNamespaceConstraints_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_listNamespaceConstraints_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_listNamespaceConstraints_presult__isset {
  _AccumuloProxy_listNamespaceConstraints_presult__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
  bool success :1;
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_listNamespaceConstraints_presult__isset;

class AccumuloProxy_listNamespaceConstraints_presult {
 public:


  virtual ~AccumuloProxy_listNamespaceConstraints_presult() throw();
  std::map<std::string, int32_t> * success;
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  NamespaceNotFoundException ouch3;

  _AccumuloProxy_listNamespaceConstraints_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

typedef struct _AccumuloProxy_testNamespaceClassLoad_args__isset {
  _AccumuloProxy_testNamespaceClassLoad_args__isset() : login(false), namespaceName(false), className(false), asTypeName(false) {}
  bool login :1;
  bool namespaceName :1;
  bool className :1;
  bool asTypeName :1;
} _AccumuloProxy_testNamespaceClassLoad_args__isset;

class AccumuloProxy_testNamespaceClassLoad_args {
 public:

  AccumuloProxy_testNamespaceClassLoad_args(const AccumuloProxy_testNamespaceClassLoad_args&);
  AccumuloProxy_testNamespaceClassLoad_args& operator=(const AccumuloProxy_testNamespaceClassLoad_args&);
  AccumuloProxy_testNamespaceClassLoad_args() : login(), namespaceName(), className(), asTypeName() {
  }

  virtual ~AccumuloProxy_testNamespaceClassLoad_args() throw();
  std::string login;
  std::string namespaceName;
  std::string className;
  std::string asTypeName;

  _AccumuloProxy_testNamespaceClassLoad_args__isset __isset;

  void __set_login(const std::string& val);

  void __set_namespaceName(const std::string& val);

  void __set_className(const std::string& val);

  void __set_asTypeName(const std::string& val);

  bool operator == (const AccumuloProxy_testNamespaceClassLoad_args & rhs) const
  {
    if (!(login == rhs.login))
      return false;
    if (!(namespaceName == rhs.namespaceName))
      return false;
    if (!(className == rhs.className))
      return false;
    if (!(asTypeName == rhs.asTypeName))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_testNamespaceClassLoad_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_testNamespaceClassLoad_args & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};


class AccumuloProxy_testNamespaceClassLoad_pargs {
 public:


  virtual ~AccumuloProxy_testNamespaceClassLoad_pargs() throw();
  const std::string* login;
  const std::string* namespaceName;
  const std::string* className;
  const std::string* asTypeName;

  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_testNamespaceClassLoad_result__isset {
  _AccumuloProxy_testNamespaceClassLoad_result__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
  bool success :1;
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_testNamespaceClassLoad_result__isset;

class AccumuloProxy_testNamespaceClassLoad_result {
 public:

  AccumuloProxy_testNamespaceClassLoad_result(const AccumuloProxy_testNamespaceClassLoad_result&);
  AccumuloProxy_testNamespaceClassLoad_result& operator=(const AccumuloProxy_testNamespaceClassLoad_result&);
  AccumuloProxy_testNamespaceClassLoad_result() : success(0) {
  }

  virtual ~AccumuloProxy_testNamespaceClassLoad_result() throw();
  bool success;
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  NamespaceNotFoundException ouch3;

  _AccumuloProxy_testNamespaceClassLoad_result__isset __isset;

  void __set_success(const bool val);

  void __set_ouch1(const AccumuloException& val);

  void __set_ouch2(const AccumuloSecurityException& val);

  void __set_ouch3(const NamespaceNotFoundException& val);

  bool operator == (const AccumuloProxy_testNamespaceClassLoad_result & rhs) const
  {
    if (!(success == rhs.success))
      return false;
    if (!(ouch1 == rhs.ouch1))
      return false;
    if (!(ouch2 == rhs.ouch2))
      return false;
    if (!(ouch3 == rhs.ouch3))
      return false;
    return true;
  }
  bool operator != (const AccumuloProxy_testNamespaceClassLoad_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloProxy_testNamespaceClassLoad_result & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

typedef struct _AccumuloProxy_testNamespaceClassLoad_presult__isset {
  _AccumuloProxy_testNamespaceClassLoad_presult__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
  bool success :1;
  bool ouch1 :1;
  bool ouch2 :1;
  bool ouch3 :1;
} _AccumuloProxy_testNamespaceClassLoad_presult__isset;

class AccumuloProxy_testNamespaceClassLoad_presult {
 public:


  virtual ~AccumuloProxy_testNamespaceClassLoad_presult() throw();
  bool* success;
  AccumuloException ouch1;
  AccumuloSecurityException ouch2;
  NamespaceNotFoundException ouch3;

  _AccumuloProxy_testNamespaceClassLoad_presult__isset __isset;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);

};

class AccumuloProxyClient : virtual public AccumuloProxyIf {
 public:
  AccumuloProxyClient(boost::shared_ptr< ::apache::thrift::protocol::TProtocol> prot) {
    setProtocol(prot);
  }
  AccumuloProxyClient(boost::shared_ptr< ::apache::thrift::protocol::TProtocol> iprot, boost::shared_ptr< ::apache::thrift::protocol::TProtocol> oprot) {
    setProtocol(iprot,oprot);
  }
 private:
  void setProtocol(boost::shared_ptr< ::apache::thrift::protocol::TProtocol> prot) {
  setProtocol(prot,prot);
  }
  void setProtocol(boost::shared_ptr< ::apache::thrift::protocol::TProtocol> iprot, boost::shared_ptr< ::apache::thrift::protocol::TProtocol> oprot) {
    piprot_=iprot;
    poprot_=oprot;
    iprot_ = iprot.get();
    oprot_ = oprot.get();
  }
 public:
  boost::shared_ptr< ::apache::thrift::protocol::TProtocol> getInputProtocol() {
    return piprot_;
  }
  boost::shared_ptr< ::apache::thrift::protocol::TProtocol> getOutputProtocol() {
    return poprot_;
  }
  void login(std::string& _return, const std::string& principal, const std::map<std::string, std::string> & loginProperties);
  void send_login(const std::string& principal, const std::map<std::string, std::string> & loginProperties);
  void recv_login(std::string& _return);
  int32_t addConstraint(const std::string& login, const std::string& tableName, const std::string& constraintClassName);
  void send_addConstraint(const std::string& login, const std::string& tableName, const std::string& constraintClassName);
  int32_t recv_addConstraint();
  void addSplits(const std::string& login, const std::string& tableName, const std::set<std::string> & splits);
  void send_addSplits(const std::string& login, const std::string& tableName, const std::set<std::string> & splits);
  void recv_addSplits();
  void attachIterator(const std::string& login, const std::string& tableName, const IteratorSetting& setting, const std::set<IteratorScope::type> & scopes);
  void send_attachIterator(const std::string& login, const std::string& tableName, const IteratorSetting& setting, const std::set<IteratorScope::type> & scopes);
  void recv_attachIterator();
  void checkIteratorConflicts(const std::string& login, const std::string& tableName, const IteratorSetting& setting, const std::set<IteratorScope::type> & scopes);
  void send_checkIteratorConflicts(const std::string& login, const std::string& tableName, const IteratorSetting& setting, const std::set<IteratorScope::type> & scopes);
  void recv_checkIteratorConflicts();
  void clearLocatorCache(const std::string& login, const std::string& tableName);
  void send_clearLocatorCache(const std::string& login, const std::string& tableName);
  void recv_clearLocatorCache();
  void cloneTable(const std::string& login, const std::string& tableName, const std::string& newTableName, const bool flush, const std::map<std::string, std::string> & propertiesToSet, const std::set<std::string> & propertiesToExclude);
  void send_cloneTable(const std::string& login, const std::string& tableName, const std::string& newTableName, const bool flush, const std::map<std::string, std::string> & propertiesToSet, const std::set<std::string> & propertiesToExclude);
  void recv_cloneTable();
  void compactTable(const std::string& login, const std::string& tableName, const std::string& startRow, const std::string& endRow, const std::vector<IteratorSetting> & iterators, const bool flush, const bool wait, const CompactionStrategyConfig& compactionStrategy);
  void send_compactTable(const std::string& login, const std::string& tableName, const std::string& startRow, const std::string& endRow, const std::vector<IteratorSetting> & iterators, const bool flush, const bool wait, const CompactionStrategyConfig& compactionStrategy);
  void recv_compactTable();
  void cancelCompaction(const std::string& login, const std::string& tableName);
  void send_cancelCompaction(const std::string& login, const std::string& tableName);
  void recv_cancelCompaction();
  void createTable(const std::string& login, const std::string& tableName, const bool versioningIter, const TimeType::type type);
  void send_createTable(const std::string& login, const std::string& tableName, const bool versioningIter, const TimeType::type type);
  void recv_createTable();
  void deleteTable(const std::string& login, const std::string& tableName);
  void send_deleteTable(const std::string& login, const std::string& tableName);
  void recv_deleteTable();
  void deleteRows(const std::string& login, const std::string& tableName, const std::string& startRow, const std::string& endRow);
  void send_deleteRows(const std::string& login, const std::string& tableName, const std::string& startRow, const std::string& endRow);
  void recv_deleteRows();
  void exportTable(const std::string& login, const std::string& tableName, const std::string& exportDir);
  void send_exportTable(const std::string& login, const std::string& tableName, const std::string& exportDir);
  void recv_exportTable();
  void flushTable(const std::string& login, const std::string& tableName, const std::string& startRow, const std::string& endRow, const bool wait);
  void send_flushTable(const std::string& login, const std::string& tableName, const std::string& startRow, const std::string& endRow, const bool wait);
  void recv_flushTable();
  void getDiskUsage(std::vector<DiskUsage> & _return, const std::string& login, const std::set<std::string> & tables);
  void send_getDiskUsage(const std::string& login, const std::set<std::string> & tables);
  void recv_getDiskUsage(std::vector<DiskUsage> & _return);
  void getLocalityGroups(std::map<std::string, std::set<std::string> > & _return, const std::string& login, const std::string& tableName);
  void send_getLocalityGroups(const std::string& login, const std::string& tableName);
  void recv_getLocalityGroups(std::map<std::string, std::set<std::string> > & _return);
  void getIteratorSetting(IteratorSetting& _return, const std::string& login, const std::string& tableName, const std::string& iteratorName, const IteratorScope::type scope);
  void send_getIteratorSetting(const std::string& login, const std::string& tableName, const std::string& iteratorName, const IteratorScope::type scope);
  void recv_getIteratorSetting(IteratorSetting& _return);
  void getMaxRow(std::string& _return, const std::string& login, const std::string& tableName, const std::set<std::string> & auths, const std::string& startRow, const bool startInclusive, const std::string& endRow, const bool endInclusive);
  void send_getMaxRow(const std::string& login, const std::string& tableName, const std::set<std::string> & auths, const std::string& startRow, const bool startInclusive, const std::string& endRow, const bool endInclusive);
  void recv_getMaxRow(std::string& _return);
  void getTableProperties(std::map<std::string, std::string> & _return, const std::string& login, const std::string& tableName);
  void send_getTableProperties(const std::string& login, const std::string& tableName);
  void recv_getTableProperties(std::map<std::string, std::string> & _return);
  void importDirectory(const std::string& login, const std::string& tableName, const std::string& importDir, const std::string& failureDir, const bool setTime);
  void send_importDirectory(const std::string& login, const std::string& tableName, const std::string& importDir, const std::string& failureDir, const bool setTime);
  void recv_importDirectory();
  void importTable(const std::string& login, const std::string& tableName, const std::string& importDir);
  void send_importTable(const std::string& login, const std::string& tableName, const std::string& importDir);
  void recv_importTable();
  void listSplits(std::vector<std::string> & _return, const std::string& login, const std::string& tableName, const int32_t maxSplits);
  void send_listSplits(const std::string& login, const std::string& tableName, const int32_t maxSplits);
  void recv_listSplits(std::vector<std::string> & _return);
  void listTables(std::set<std::string> & _return, const std::string& login);
  void send_listTables(const std::string& login);
  void recv_listTables(std::set<std::string> & _return);
  void listIterators(std::map<std::string, std::set<IteratorScope::type> > & _return, const std::string& login, const std::string& tableName);
  void send_listIterators(const std::string& login, const std::string& tableName);
  void recv_listIterators(std::map<std::string, std::set<IteratorScope::type> > & _return);
  void listConstraints(std::map<std::string, int32_t> & _return, const std::string& login, const std::string& tableName);
  void send_listConstraints(const std::string& login, const std::string& tableName);
  void recv_listConstraints(std::map<std::string, int32_t> & _return);
  void mergeTablets(const std::string& login, const std::string& tableName, const std::string& startRow, const std::string& endRow);
  void send_mergeTablets(const std::string& login, const std::string& tableName, const std::string& startRow, const std::string& endRow);
  void recv_mergeTablets();
  void offlineTable(const std::string& login, const std::string& tableName, const bool wait);
  void send_offlineTable(const std::string& login, const std::string& tableName, const bool wait);
  void recv_offlineTable();
  void onlineTable(const std::string& login, const std::string& tableName, const bool wait);
  void send_onlineTable(const std::string& login, const std::string& tableName, const bool wait);
  void recv_onlineTable();
  void removeConstraint(const std::string& login, const std::string& tableName, const int32_t constraint);
  void send_removeConstraint(const std::string& login, const std::string& tableName, const int32_t constraint);
  void recv_removeConstraint();
  void removeIterator(const std::string& login, const std::string& tableName, const std::string& iterName, const std::set<IteratorScope::type> & scopes);
  void send_removeIterator(const std::string& login, const std::string& tableName, const std::string& iterName, const std::set<IteratorScope::type> & scopes);
  void recv_removeIterator();
  void removeTableProperty(const std::string& login, const std::string& tableName, const std::string& property);
  void send_removeTableProperty(const std::string& login, const std::string& tableName, const std::string& property);
  void recv_removeTableProperty();
  void renameTable(const std::string& login, const std::string& oldTableName, const std::string& newTableName);
  void send_renameTable(const std::string& login, const std::string& oldTableName, const std::string& newTableName);
  void recv_renameTable();
  void setLocalityGroups(const std::string& login, const std::string& tableName, const std::map<std::string, std::set<std::string> > & groups);
  void send_setLocalityGroups(const std::string& login, const std::string& tableName, const std::map<std::string, std::set<std::string> > & groups);
  void recv_setLocalityGroups();
  void setTableProperty(const std::string& login, const std::string& tableName, const std::string& property, const std::string& value);
  void send_setTableProperty(const std::string& login, const std::string& tableName, const std::string& property, const std::string& value);
  void recv_setTableProperty();
  void splitRangeByTablets(std::set<Range> & _return, const std::string& login, const std::string& tableName, const Range& range, const int32_t maxSplits);
  void send_splitRangeByTablets(const std::string& login, const std::string& tableName, const Range& range, const int32_t maxSplits);
  void recv_splitRangeByTablets(std::set<Range> & _return);
  bool tableExists(const std::string& login, const std::string& tableName);
  void send_tableExists(const std::string& login, const std::string& tableName);
  bool recv_tableExists();
  void tableIdMap(std::map<std::string, std::string> & _return, const std::string& login);
  void send_tableIdMap(const std::string& login);
  void recv_tableIdMap(std::map<std::string, std::string> & _return);
  bool testTableClassLoad(const std::string& login, const std::string& tableName, const std::string& className, const std::string& asTypeName);
  void send_testTableClassLoad(const std::string& login, const std::string& tableName, const std::string& className, const std::string& asTypeName);
  bool recv_testTableClassLoad();
  void pingTabletServer(const std::string& login, const std::string& tserver);
  void send_pingTabletServer(const std::string& login, const std::string& tserver);
  void recv_pingTabletServer();
  void getActiveScans(std::vector<ActiveScan> & _return, const std::string& login, const std::string& tserver);
  void send_getActiveScans(const std::string& login, const std::string& tserver);
  void recv_getActiveScans(std::vector<ActiveScan> & _return);
  void getActiveCompactions(std::vector<ActiveCompaction> & _return, const std::string& login, const std::string& tserver);
  void send_getActiveCompactions(const std::string& login, const std::string& tserver);
  void recv_getActiveCompactions(std::vector<ActiveCompaction> & _return);
  void getSiteConfiguration(std::map<std::string, std::string> & _return, const std::string& login);
  void send_getSiteConfiguration(const std::string& login);
  void recv_getSiteConfiguration(std::map<std::string, std::string> & _return);
  void getSystemConfiguration(std::map<std::string, std::string> & _return, const std::string& login);
  void send_getSystemConfiguration(const std::string& login);
  void recv_getSystemConfiguration(std::map<std::string, std::string> & _return);
  void getTabletServers(std::vector<std::string> & _return, const std::string& login);
  void send_getTabletServers(const std::string& login);
  void recv_getTabletServers(std::vector<std::string> & _return);
  void removeProperty(const std::string& login, const std::string& property);
  void send_removeProperty(const std::string& login, const std::string& property);
  void recv_removeProperty();
  void setProperty(const std::string& login, const std::string& property, const std::string& value);
  void send_setProperty(const std::string& login, const std::string& property, const std::string& value);
  void recv_setProperty();
  bool testClassLoad(const std::string& login, const std::string& className, const std::string& asTypeName);
  void send_testClassLoad(const std::string& login, const std::string& className, const std::string& asTypeName);
  bool recv_testClassLoad();
  bool authenticateUser(const std::string& login, const std::string& user, const std::map<std::string, std::string> & properties);
  void send_authenticateUser(const std::string& login, const std::string& user, const std::map<std::string, std::string> & properties);
  bool recv_authenticateUser();
  void changeUserAuthorizations(const std::string& login, const std::string& user, const std::set<std::string> & authorizations);
  void send_changeUserAuthorizations(const std::string& login, const std::string& user, const std::set<std::string> & authorizations);
  void recv_changeUserAuthorizations();
  void changeLocalUserPassword(const std::string& login, const std::string& user, const std::string& password);
  void send_changeLocalUserPassword(const std::string& login, const std::string& user, const std::string& password);
  void recv_changeLocalUserPassword();
  void createLocalUser(const std::string& login, const std::string& user, const std::string& password);
  void send_createLocalUser(const std::string& login, const std::string& user, const std::string& password);
  void recv_createLocalUser();
  void dropLocalUser(const std::string& login, const std::string& user);
  void send_dropLocalUser(const std::string& login, const std::string& user);
  void recv_dropLocalUser();
  void getUserAuthorizations(std::vector<std::string> & _return, const std::string& login, const std::string& user);
  void send_getUserAuthorizations(const std::string& login, const std::string& user);
  void recv_getUserAuthorizations(std::vector<std::string> & _return);
  void grantSystemPermission(const std::string& login, const std::string& user, const SystemPermission::type perm);
  void send_grantSystemPermission(const std::string& login, const std::string& user, const SystemPermission::type perm);
  void recv_grantSystemPermission();
  void grantTablePermission(const std::string& login, const std::string& user, const std::string& table, const TablePermission::type perm);
  void send_grantTablePermission(const std::string& login, const std::string& user, const std::string& table, const TablePermission::type perm);
  void recv_grantTablePermission();
  bool hasSystemPermission(const std::string& login, const std::string& user, const SystemPermission::type perm);
  void send_hasSystemPermission(const std::string& login, const std::string& user, const SystemPermission::type perm);
  bool recv_hasSystemPermission();
  bool hasTablePermission(const std::string& login, const std::string& user, const std::string& table, const TablePermission::type perm);
  void send_hasTablePermission(const std::string& login, const std::string& user, const std::string& table, const TablePermission::type perm);
  bool recv_hasTablePermission();
  void listLocalUsers(std::set<std::string> & _return, const std::string& login);
  void send_listLocalUsers(const std::string& login);
  void recv_listLocalUsers(std::set<std::string> & _return);
  void revokeSystemPermission(const std::string& login, const std::string& user, const SystemPermission::type perm);
  void send_revokeSystemPermission(const std::string& login, const std::string& user, const SystemPermission::type perm);
  void recv_revokeSystemPermission();
  void revokeTablePermission(const std::string& login, const std::string& user, const std::string& table, const TablePermission::type perm);
  void send_revokeTablePermission(const std::string& login, const std::string& user, const std::string& table, const TablePermission::type perm);
  void recv_revokeTablePermission();
  void grantNamespacePermission(const std::string& login, const std::string& user, const std::string& namespaceName, const NamespacePermission::type perm);
  void send_grantNamespacePermission(const std::string& login, const std::string& user, const std::string& namespaceName, const NamespacePermission::type perm);
  void recv_grantNamespacePermission();
  bool hasNamespacePermission(const std::string& login, const std::string& user, const std::string& namespaceName, const NamespacePermission::type perm);
  void send_hasNamespacePermission(const std::string& login, const std::string& user, const std::string& namespaceName, const NamespacePermission::type perm);
  bool recv_hasNamespacePermission();
  void revokeNamespacePermission(const std::string& login, const std::string& user, const std::string& namespaceName, const NamespacePermission::type perm);
  void send_revokeNamespacePermission(const std::string& login, const std::string& user, const std::string& namespaceName, const NamespacePermission::type perm);
  void recv_revokeNamespacePermission();
  void createBatchScanner(std::string& _return, const std::string& login, const std::string& tableName, const BatchScanOptions& options);
  void send_createBatchScanner(const std::string& login, const std::string& tableName, const BatchScanOptions& options);
  void recv_createBatchScanner(std::string& _return);
  void createScanner(std::string& _return, const std::string& login, const std::string& tableName, const ScanOptions& options);
  void send_createScanner(const std::string& login, const std::string& tableName, const ScanOptions& options);
  void recv_createScanner(std::string& _return);
  bool hasNext(const std::string& scanner);
  void send_hasNext(const std::string& scanner);
  bool recv_hasNext();
  void nextEntry(KeyValueAndPeek& _return, const std::string& scanner);
  void send_nextEntry(const std::string& scanner);
  void recv_nextEntry(KeyValueAndPeek& _return);
  void nextK(ScanResult& _return, const std::string& scanner, const int32_t k);
  void send_nextK(const std::string& scanner, const int32_t k);
  void recv_nextK(ScanResult& _return);
  void closeScanner(const std::string& scanner);
  void send_closeScanner(const std::string& scanner);
  void recv_closeScanner();
  void updateAndFlush(const std::string& login, const std::string& tableName, const std::map<std::string, std::vector<ColumnUpdate> > & cells);
  void send_updateAndFlush(const std::string& login, const std::string& tableName, const std::map<std::string, std::vector<ColumnUpdate> > & cells);
  void recv_updateAndFlush();
  void createWriter(std::string& _return, const std::string& login, const std::string& tableName, const WriterOptions& opts);
  void send_createWriter(const std::string& login, const std::string& tableName, const WriterOptions& opts);
  void recv_createWriter(std::string& _return);
  void update(const std::string& writer, const std::map<std::string, std::vector<ColumnUpdate> > & cells);
  void send_update(const std::string& writer, const std::map<std::string, std::vector<ColumnUpdate> > & cells);
  void flush(const std::string& writer);
  void send_flush(const std::string& writer);
  void recv_flush();
  void closeWriter(const std::string& writer);
  void send_closeWriter(const std::string& writer);
  void recv_closeWriter();
  ConditionalStatus::type updateRowConditionally(const std::string& login, const std::string& tableName, const std::string& row, const ConditionalUpdates& updates);
  void send_updateRowConditionally(const std::string& login, const std::string& tableName, const std::string& row, const ConditionalUpdates& updates);
  ConditionalStatus::type recv_updateRowConditionally();
  void createConditionalWriter(std::string& _return, const std::string& login, const std::string& tableName, const ConditionalWriterOptions& options);
  void send_createConditionalWriter(const std::string& login, const std::string& tableName, const ConditionalWriterOptions& options);
  void recv_createConditionalWriter(std::string& _return);
  void updateRowsConditionally(std::map<std::string, ConditionalStatus::type> & _return, const std::string& conditionalWriter, const std::map<std::string, ConditionalUpdates> & updates);
  void send_updateRowsConditionally(const std::string& conditionalWriter, const std::map<std::string, ConditionalUpdates> & updates);
  void recv_updateRowsConditionally(std::map<std::string, ConditionalStatus::type> & _return);
  void closeConditionalWriter(const std::string& conditionalWriter);
  void send_closeConditionalWriter(const std::string& conditionalWriter);
  void recv_closeConditionalWriter();
  void getRowRange(Range& _return, const std::string& row);
  void send_getRowRange(const std::string& row);
  void recv_getRowRange(Range& _return);
  void getFollowing(Key& _return, const Key& key, const PartialKey::type part);
  void send_getFollowing(const Key& key, const PartialKey::type part);
  void recv_getFollowing(Key& _return);
  void systemNamespace(std::string& _return);
  void send_systemNamespace();
  void recv_systemNamespace(std::string& _return);
  void defaultNamespace(std::string& _return);
  void send_defaultNamespace();
  void recv_defaultNamespace(std::string& _return);
  void listNamespaces(std::vector<std::string> & _return, const std::string& login);
  void send_listNamespaces(const std::string& login);
  void recv_listNamespaces(std::vector<std::string> & _return);
  bool namespaceExists(const std::string& login, const std::string& namespaceName);
  void send_namespaceExists(const std::string& login, const std::string& namespaceName);
  bool recv_namespaceExists();
  void createNamespace(const std::string& login, const std::string& namespaceName);
  void send_createNamespace(const std::string& login, const std::string& namespaceName);
  void recv_createNamespace();
  void deleteNamespace(const std::string& login, const std::string& namespaceName);
  void send_deleteNamespace(const std::string& login, const std::string& namespaceName);
  void recv_deleteNamespace();
  void renameNamespace(const std::string& login, const std::string& oldNamespaceName, const std::string& newNamespaceName);
  void send_renameNamespace(const std::string& login, const std::string& oldNamespaceName, const std::string& newNamespaceName);
  void recv_renameNamespace();
  void setNamespaceProperty(const std::string& login, const std::string& namespaceName, const std::string& property, const std::string& value);
  void send_setNamespaceProperty(const std::string& login, const std::string& namespaceName, const std::string& property, const std::string& value);
  void recv_setNamespaceProperty();
  void removeNamespaceProperty(const std::string& login, const std::string& namespaceName, const std::string& property);
  void send_removeNamespaceProperty(const std::string& login, const std::string& namespaceName, const std::string& property);
  void recv_removeNamespaceProperty();
  void getNamespaceProperties(std::map<std::string, std::string> & _return, const std::string& login, const std::string& namespaceName);
  void send_getNamespaceProperties(const std::string& login, const std::string& namespaceName);
  void recv_getNamespaceProperties(std::map<std::string, std::string> & _return);
  void namespaceIdMap(std::map<std::string, std::string> & _return, const std::string& login);
  void send_namespaceIdMap(const std::string& login);
  void recv_namespaceIdMap(std::map<std::string, std::string> & _return);
  void attachNamespaceIterator(const std::string& login, const std::string& namespaceName, const IteratorSetting& setting, const std::set<IteratorScope::type> & scopes);
  void send_attachNamespaceIterator(const std::string& login, const std::string& namespaceName, const IteratorSetting& setting, const std::set<IteratorScope::type> & scopes);
  void recv_attachNamespaceIterator();
  void removeNamespaceIterator(const std::string& login, const std::string& namespaceName, const std::string& name, const std::set<IteratorScope::type> & scopes);
  void send_removeNamespaceIterator(const std::string& login, const std::string& namespaceName, const std::string& name, const std::set<IteratorScope::type> & scopes);
  void recv_removeNamespaceIterator();
  void getNamespaceIteratorSetting(IteratorSetting& _return, const std::string& login, const std::string& namespaceName, const std::string& name, const IteratorScope::type scope);
  void send_getNamespaceIteratorSetting(const std::string& login, const std::string& namespaceName, const std::string& name, const IteratorScope::type scope);
  void recv_getNamespaceIteratorSetting(IteratorSetting& _return);
  void listNamespaceIterators(std::map<std::string, std::set<IteratorScope::type> > & _return, const std::string& login, const std::string& namespaceName);
  void send_listNamespaceIterators(const std::string& login, const std::string& namespaceName);
  void recv_listNamespaceIterators(std::map<std::string, std::set<IteratorScope::type> > & _return);
  void checkNamespaceIteratorConflicts(const std::string& login, const std::string& namespaceName, const IteratorSetting& setting, const std::set<IteratorScope::type> & scopes);
  void send_checkNamespaceIteratorConflicts(const std::string& login, const std::string& namespaceName, const IteratorSetting& setting, const std::set<IteratorScope::type> & scopes);
  void recv_checkNamespaceIteratorConflicts();
  int32_t addNamespaceConstraint(const std::string& login, const std::string& namespaceName, const std::string& constraintClassName);
  void send_addNamespaceConstraint(const std::string& login, const std::string& namespaceName, const std::string& constraintClassName);
  int32_t recv_addNamespaceConstraint();
  void removeNamespaceConstraint(const std::string& login, const std::string& namespaceName, const int32_t id);
  void send_removeNamespaceConstraint(const std::string& login, const std::string& namespaceName, const int32_t id);
  void recv_removeNamespaceConstraint();
  void listNamespaceConstraints(std::map<std::string, int32_t> & _return, const std::string& login, const std::string& namespaceName);
  void send_listNamespaceConstraints(const std::string& login, const std::string& namespaceName);
  void recv_listNamespaceConstraints(std::map<std::string, int32_t> & _return);
  bool testNamespaceClassLoad(const std::string& login, const std::string& namespaceName, const std::string& className, const std::string& asTypeName);
  void send_testNamespaceClassLoad(const std::string& login, const std::string& namespaceName, const std::string& className, const std::string& asTypeName);
  bool recv_testNamespaceClassLoad();
 protected:
  boost::shared_ptr< ::apache::thrift::protocol::TProtocol> piprot_;
  boost::shared_ptr< ::apache::thrift::protocol::TProtocol> poprot_;
  ::apache::thrift::protocol::TProtocol* iprot_;
  ::apache::thrift::protocol::TProtocol* oprot_;
};

class AccumuloProxyProcessor : public ::apache::thrift::TDispatchProcessor {
 protected:
  boost::shared_ptr<AccumuloProxyIf> iface_;
  virtual bool dispatchCall(::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, const std::string& fname, int32_t seqid, void* callContext);
 private:
  typedef  void (AccumuloProxyProcessor::*ProcessFunction)(int32_t, ::apache::thrift::protocol::TProtocol*, ::apache::thrift::protocol::TProtocol*, void*);
  typedef std::map<std::string, ProcessFunction> ProcessMap;
  ProcessMap processMap_;
  void process_login(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_addConstraint(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_addSplits(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_attachIterator(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_checkIteratorConflicts(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_clearLocatorCache(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_cloneTable(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_compactTable(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_cancelCompaction(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_createTable(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_deleteTable(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_deleteRows(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_exportTable(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_flushTable(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_getDiskUsage(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_getLocalityGroups(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_getIteratorSetting(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_getMaxRow(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_getTableProperties(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_importDirectory(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_importTable(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_listSplits(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_listTables(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_listIterators(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_listConstraints(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_mergeTablets(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_offlineTable(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_onlineTable(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_removeConstraint(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_removeIterator(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_removeTableProperty(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_renameTable(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_setLocalityGroups(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_setTableProperty(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_splitRangeByTablets(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_tableExists(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_tableIdMap(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_testTableClassLoad(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_pingTabletServer(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_getActiveScans(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_getActiveCompactions(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_getSiteConfiguration(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_getSystemConfiguration(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_getTabletServers(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_removeProperty(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_setProperty(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_testClassLoad(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_authenticateUser(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_changeUserAuthorizations(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_changeLocalUserPassword(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_createLocalUser(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_dropLocalUser(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_getUserAuthorizations(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_grantSystemPermission(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_grantTablePermission(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_hasSystemPermission(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_hasTablePermission(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_listLocalUsers(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_revokeSystemPermission(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_revokeTablePermission(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_grantNamespacePermission(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_hasNamespacePermission(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_revokeNamespacePermission(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_createBatchScanner(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_createScanner(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_hasNext(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_nextEntry(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_nextK(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_closeScanner(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_updateAndFlush(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_createWriter(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_update(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_flush(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_closeWriter(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_updateRowConditionally(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_createConditionalWriter(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_updateRowsConditionally(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_closeConditionalWriter(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_getRowRange(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_getFollowing(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_systemNamespace(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_defaultNamespace(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_listNamespaces(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_namespaceExists(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_createNamespace(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_deleteNamespace(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_renameNamespace(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_setNamespaceProperty(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_removeNamespaceProperty(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_getNamespaceProperties(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_namespaceIdMap(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_attachNamespaceIterator(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_removeNamespaceIterator(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_getNamespaceIteratorSetting(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_listNamespaceIterators(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_checkNamespaceIteratorConflicts(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_addNamespaceConstraint(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_removeNamespaceConstraint(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_listNamespaceConstraints(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  void process_testNamespaceClassLoad(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
 public:
  AccumuloProxyProcessor(boost::shared_ptr<AccumuloProxyIf> iface) :
    iface_(iface) {
    processMap_["login"] = &AccumuloProxyProcessor::process_login;
    processMap_["addConstraint"] = &AccumuloProxyProcessor::process_addConstraint;
    processMap_["addSplits"] = &AccumuloProxyProcessor::process_addSplits;
    processMap_["attachIterator"] = &AccumuloProxyProcessor::process_attachIterator;
    processMap_["checkIteratorConflicts"] = &AccumuloProxyProcessor::process_checkIteratorConflicts;
    processMap_["clearLocatorCache"] = &AccumuloProxyProcessor::process_clearLocatorCache;
    processMap_["cloneTable"] = &AccumuloProxyProcessor::process_cloneTable;
    processMap_["compactTable"] = &AccumuloProxyProcessor::process_compactTable;
    processMap_["cancelCompaction"] = &AccumuloProxyProcessor::process_cancelCompaction;
    processMap_["createTable"] = &AccumuloProxyProcessor::process_createTable;
    processMap_["deleteTable"] = &AccumuloProxyProcessor::process_deleteTable;
    processMap_["deleteRows"] = &AccumuloProxyProcessor::process_deleteRows;
    processMap_["exportTable"] = &AccumuloProxyProcessor::process_exportTable;
    processMap_["flushTable"] = &AccumuloProxyProcessor::process_flushTable;
    processMap_["getDiskUsage"] = &AccumuloProxyProcessor::process_getDiskUsage;
    processMap_["getLocalityGroups"] = &AccumuloProxyProcessor::process_getLocalityGroups;
    processMap_["getIteratorSetting"] = &AccumuloProxyProcessor::process_getIteratorSetting;
    processMap_["getMaxRow"] = &AccumuloProxyProcessor::process_getMaxRow;
    processMap_["getTableProperties"] = &AccumuloProxyProcessor::process_getTableProperties;
    processMap_["importDirectory"] = &AccumuloProxyProcessor::process_importDirectory;
    processMap_["importTable"] = &AccumuloProxyProcessor::process_importTable;
    processMap_["listSplits"] = &AccumuloProxyProcessor::process_listSplits;
    processMap_["listTables"] = &AccumuloProxyProcessor::process_listTables;
    processMap_["listIterators"] = &AccumuloProxyProcessor::process_listIterators;
    processMap_["listConstraints"] = &AccumuloProxyProcessor::process_listConstraints;
    processMap_["mergeTablets"] = &AccumuloProxyProcessor::process_mergeTablets;
    processMap_["offlineTable"] = &AccumuloProxyProcessor::process_offlineTable;
    processMap_["onlineTable"] = &AccumuloProxyProcessor::process_onlineTable;
    processMap_["removeConstraint"] = &AccumuloProxyProcessor::process_removeConstraint;
    processMap_["removeIterator"] = &AccumuloProxyProcessor::process_removeIterator;
    processMap_["removeTableProperty"] = &AccumuloProxyProcessor::process_removeTableProperty;
    processMap_["renameTable"] = &AccumuloProxyProcessor::process_renameTable;
    processMap_["setLocalityGroups"] = &AccumuloProxyProcessor::process_setLocalityGroups;
    processMap_["setTableProperty"] = &AccumuloProxyProcessor::process_setTableProperty;
    processMap_["splitRangeByTablets"] = &AccumuloProxyProcessor::process_splitRangeByTablets;
    processMap_["tableExists"] = &AccumuloProxyProcessor::process_tableExists;
    processMap_["tableIdMap"] = &AccumuloProxyProcessor::process_tableIdMap;
    processMap_["testTableClassLoad"] = &AccumuloProxyProcessor::process_testTableClassLoad;
    processMap_["pingTabletServer"] = &AccumuloProxyProcessor::process_pingTabletServer;
    processMap_["getActiveScans"] = &AccumuloProxyProcessor::process_getActiveScans;
    processMap_["getActiveCompactions"] = &AccumuloProxyProcessor::process_getActiveCompactions;
    processMap_["getSiteConfiguration"] = &AccumuloProxyProcessor::process_getSiteConfiguration;
    processMap_["getSystemConfiguration"] = &AccumuloProxyProcessor::process_getSystemConfiguration;
    processMap_["getTabletServers"] = &AccumuloProxyProcessor::process_getTabletServers;
    processMap_["removeProperty"] = &AccumuloProxyProcessor::process_removeProperty;
    processMap_["setProperty"] = &AccumuloProxyProcessor::process_setProperty;
    processMap_["testClassLoad"] = &AccumuloProxyProcessor::process_testClassLoad;
    processMap_["authenticateUser"] = &AccumuloProxyProcessor::process_authenticateUser;
    processMap_["changeUserAuthorizations"] = &AccumuloProxyProcessor::process_changeUserAuthorizations;
    processMap_["changeLocalUserPassword"] = &AccumuloProxyProcessor::process_changeLocalUserPassword;
    processMap_["createLocalUser"] = &AccumuloProxyProcessor::process_createLocalUser;
    processMap_["dropLocalUser"] = &AccumuloProxyProcessor::process_dropLocalUser;
    processMap_["getUserAuthorizations"] = &AccumuloProxyProcessor::process_getUserAuthorizations;
    processMap_["grantSystemPermission"] = &AccumuloProxyProcessor::process_grantSystemPermission;
    processMap_["grantTablePermission"] = &AccumuloProxyProcessor::process_grantTablePermission;
    processMap_["hasSystemPermission"] = &AccumuloProxyProcessor::process_hasSystemPermission;
    processMap_["hasTablePermission"] = &AccumuloProxyProcessor::process_hasTablePermission;
    processMap_["listLocalUsers"] = &AccumuloProxyProcessor::process_listLocalUsers;
    processMap_["revokeSystemPermission"] = &AccumuloProxyProcessor::process_revokeSystemPermission;
    processMap_["revokeTablePermission"] = &AccumuloProxyProcessor::process_revokeTablePermission;
    processMap_["grantNamespacePermission"] = &AccumuloProxyProcessor::process_grantNamespacePermission;
    processMap_["hasNamespacePermission"] = &AccumuloProxyProcessor::process_hasNamespacePermission;
    processMap_["revokeNamespacePermission"] = &AccumuloProxyProcessor::process_revokeNamespacePermission;
    processMap_["createBatchScanner"] = &AccumuloProxyProcessor::process_createBatchScanner;
    processMap_["createScanner"] = &AccumuloProxyProcessor::process_createScanner;
    processMap_["hasNext"] = &AccumuloProxyProcessor::process_hasNext;
    processMap_["nextEntry"] = &AccumuloProxyProcessor::process_nextEntry;
    processMap_["nextK"] = &AccumuloProxyProcessor::process_nextK;
    processMap_["closeScanner"] = &AccumuloProxyProcessor::process_closeScanner;
    processMap_["updateAndFlush"] = &AccumuloProxyProcessor::process_updateAndFlush;
    processMap_["createWriter"] = &AccumuloProxyProcessor::process_createWriter;
    processMap_["update"] = &AccumuloProxyProcessor::process_update;
    processMap_["flush"] = &AccumuloProxyProcessor::process_flush;
    processMap_["closeWriter"] = &AccumuloProxyProcessor::process_closeWriter;
    processMap_["updateRowConditionally"] = &AccumuloProxyProcessor::process_updateRowConditionally;
    processMap_["createConditionalWriter"] = &AccumuloProxyProcessor::process_createConditionalWriter;
    processMap_["updateRowsConditionally"] = &AccumuloProxyProcessor::process_updateRowsConditionally;
    processMap_["closeConditionalWriter"] = &AccumuloProxyProcessor::process_closeConditionalWriter;
    processMap_["getRowRange"] = &AccumuloProxyProcessor::process_getRowRange;
    processMap_["getFollowing"] = &AccumuloProxyProcessor::process_getFollowing;
    processMap_["systemNamespace"] = &AccumuloProxyProcessor::process_systemNamespace;
    processMap_["defaultNamespace"] = &AccumuloProxyProcessor::process_defaultNamespace;
    processMap_["listNamespaces"] = &AccumuloProxyProcessor::process_listNamespaces;
    processMap_["namespaceExists"] = &AccumuloProxyProcessor::process_namespaceExists;
    processMap_["createNamespace"] = &AccumuloProxyProcessor::process_createNamespace;
    processMap_["deleteNamespace"] = &AccumuloProxyProcessor::process_deleteNamespace;
    processMap_["renameNamespace"] = &AccumuloProxyProcessor::process_renameNamespace;
    processMap_["setNamespaceProperty"] = &AccumuloProxyProcessor::process_setNamespaceProperty;
    processMap_["removeNamespaceProperty"] = &AccumuloProxyProcessor::process_removeNamespaceProperty;
    processMap_["getNamespaceProperties"] = &AccumuloProxyProcessor::process_getNamespaceProperties;
    processMap_["namespaceIdMap"] = &AccumuloProxyProcessor::process_namespaceIdMap;
    processMap_["attachNamespaceIterator"] = &AccumuloProxyProcessor::process_attachNamespaceIterator;
    processMap_["removeNamespaceIterator"] = &AccumuloProxyProcessor::process_removeNamespaceIterator;
    processMap_["getNamespaceIteratorSetting"] = &AccumuloProxyProcessor::process_getNamespaceIteratorSetting;
    processMap_["listNamespaceIterators"] = &AccumuloProxyProcessor::process_listNamespaceIterators;
    processMap_["checkNamespaceIteratorConflicts"] = &AccumuloProxyProcessor::process_checkNamespaceIteratorConflicts;
    processMap_["addNamespaceConstraint"] = &AccumuloProxyProcessor::process_addNamespaceConstraint;
    processMap_["removeNamespaceConstraint"] = &AccumuloProxyProcessor::process_removeNamespaceConstraint;
    processMap_["listNamespaceConstraints"] = &AccumuloProxyProcessor::process_listNamespaceConstraints;
    processMap_["testNamespaceClassLoad"] = &AccumuloProxyProcessor::process_testNamespaceClassLoad;
  }

  virtual ~AccumuloProxyProcessor() {}
};

class AccumuloProxyProcessorFactory : public ::apache::thrift::TProcessorFactory {
 public:
  AccumuloProxyProcessorFactory(const ::boost::shared_ptr< AccumuloProxyIfFactory >& handlerFactory) :
      handlerFactory_(handlerFactory) {}

  ::boost::shared_ptr< ::apache::thrift::TProcessor > getProcessor(const ::apache::thrift::TConnectionInfo& connInfo);

 protected:
  ::boost::shared_ptr< AccumuloProxyIfFactory > handlerFactory_;
};

class AccumuloProxyMultiface : virtual public AccumuloProxyIf {
 public:
  AccumuloProxyMultiface(std::vector<boost::shared_ptr<AccumuloProxyIf> >& ifaces) : ifaces_(ifaces) {
  }
  virtual ~AccumuloProxyMultiface() {}
 protected:
  std::vector<boost::shared_ptr<AccumuloProxyIf> > ifaces_;
  AccumuloProxyMultiface() {}
  void add(boost::shared_ptr<AccumuloProxyIf> iface) {
    ifaces_.push_back(iface);
  }
 public:
  void login(std::string& _return, const std::string& principal, const std::map<std::string, std::string> & loginProperties) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->login(_return, principal, loginProperties);
    }
    ifaces_[i]->login(_return, principal, loginProperties);
    return;
  }

  int32_t addConstraint(const std::string& login, const std::string& tableName, const std::string& constraintClassName) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->addConstraint(login, tableName, constraintClassName);
    }
    return ifaces_[i]->addConstraint(login, tableName, constraintClassName);
  }

  void addSplits(const std::string& login, const std::string& tableName, const std::set<std::string> & splits) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->addSplits(login, tableName, splits);
    }
    ifaces_[i]->addSplits(login, tableName, splits);
  }

  void attachIterator(const std::string& login, const std::string& tableName, const IteratorSetting& setting, const std::set<IteratorScope::type> & scopes) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->attachIterator(login, tableName, setting, scopes);
    }
    ifaces_[i]->attachIterator(login, tableName, setting, scopes);
  }

  void checkIteratorConflicts(const std::string& login, const std::string& tableName, const IteratorSetting& setting, const std::set<IteratorScope::type> & scopes) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->checkIteratorConflicts(login, tableName, setting, scopes);
    }
    ifaces_[i]->checkIteratorConflicts(login, tableName, setting, scopes);
  }

  void clearLocatorCache(const std::string& login, const std::string& tableName) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->clearLocatorCache(login, tableName);
    }
    ifaces_[i]->clearLocatorCache(login, tableName);
  }

  void cloneTable(const std::string& login, const std::string& tableName, const std::string& newTableName, const bool flush, const std::map<std::string, std::string> & propertiesToSet, const std::set<std::string> & propertiesToExclude) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->cloneTable(login, tableName, newTableName, flush, propertiesToSet, propertiesToExclude);
    }
    ifaces_[i]->cloneTable(login, tableName, newTableName, flush, propertiesToSet, propertiesToExclude);
  }

  void compactTable(const std::string& login, const std::string& tableName, const std::string& startRow, const std::string& endRow, const std::vector<IteratorSetting> & iterators, const bool flush, const bool wait, const CompactionStrategyConfig& compactionStrategy) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->compactTable(login, tableName, startRow, endRow, iterators, flush, wait, compactionStrategy);
    }
    ifaces_[i]->compactTable(login, tableName, startRow, endRow, iterators, flush, wait, compactionStrategy);
  }

  void cancelCompaction(const std::string& login, const std::string& tableName) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->cancelCompaction(login, tableName);
    }
    ifaces_[i]->cancelCompaction(login, tableName);
  }

  void createTable(const std::string& login, const std::string& tableName, const bool versioningIter, const TimeType::type type) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->createTable(login, tableName, versioningIter, type);
    }
    ifaces_[i]->createTable(login, tableName, versioningIter, type);
  }

  void deleteTable(const std::string& login, const std::string& tableName) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->deleteTable(login, tableName);
    }
    ifaces_[i]->deleteTable(login, tableName);
  }

  void deleteRows(const std::string& login, const std::string& tableName, const std::string& startRow, const std::string& endRow) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->deleteRows(login, tableName, startRow, endRow);
    }
    ifaces_[i]->deleteRows(login, tableName, startRow, endRow);
  }

  void exportTable(const std::string& login, const std::string& tableName, const std::string& exportDir) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->exportTable(login, tableName, exportDir);
    }
    ifaces_[i]->exportTable(login, tableName, exportDir);
  }

  void flushTable(const std::string& login, const std::string& tableName, const std::string& startRow, const std::string& endRow, const bool wait) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->flushTable(login, tableName, startRow, endRow, wait);
    }
    ifaces_[i]->flushTable(login, tableName, startRow, endRow, wait);
  }

  void getDiskUsage(std::vector<DiskUsage> & _return, const std::string& login, const std::set<std::string> & tables) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->getDiskUsage(_return, login, tables);
    }
    ifaces_[i]->getDiskUsage(_return, login, tables);
    return;
  }

  void getLocalityGroups(std::map<std::string, std::set<std::string> > & _return, const std::string& login, const std::string& tableName) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->getLocalityGroups(_return, login, tableName);
    }
    ifaces_[i]->getLocalityGroups(_return, login, tableName);
    return;
  }

  void getIteratorSetting(IteratorSetting& _return, const std::string& login, const std::string& tableName, const std::string& iteratorName, const IteratorScope::type scope) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->getIteratorSetting(_return, login, tableName, iteratorName, scope);
    }
    ifaces_[i]->getIteratorSetting(_return, login, tableName, iteratorName, scope);
    return;
  }

  void getMaxRow(std::string& _return, const std::string& login, const std::string& tableName, const std::set<std::string> & auths, const std::string& startRow, const bool startInclusive, const std::string& endRow, const bool endInclusive) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->getMaxRow(_return, login, tableName, auths, startRow, startInclusive, endRow, endInclusive);
    }
    ifaces_[i]->getMaxRow(_return, login, tableName, auths, startRow, startInclusive, endRow, endInclusive);
    return;
  }

  void getTableProperties(std::map<std::string, std::string> & _return, const std::string& login, const std::string& tableName) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->getTableProperties(_return, login, tableName);
    }
    ifaces_[i]->getTableProperties(_return, login, tableName);
    return;
  }

  void importDirectory(const std::string& login, const std::string& tableName, const std::string& importDir, const std::string& failureDir, const bool setTime) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->importDirectory(login, tableName, importDir, failureDir, setTime);
    }
    ifaces_[i]->importDirectory(login, tableName, importDir, failureDir, setTime);
  }

  void importTable(const std::string& login, const std::string& tableName, const std::string& importDir) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->importTable(login, tableName, importDir);
    }
    ifaces_[i]->importTable(login, tableName, importDir);
  }

  void listSplits(std::vector<std::string> & _return, const std::string& login, const std::string& tableName, const int32_t maxSplits) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->listSplits(_return, login, tableName, maxSplits);
    }
    ifaces_[i]->listSplits(_return, login, tableName, maxSplits);
    return;
  }

  void listTables(std::set<std::string> & _return, const std::string& login) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->listTables(_return, login);
    }
    ifaces_[i]->listTables(_return, login);
    return;
  }

  void listIterators(std::map<std::string, std::set<IteratorScope::type> > & _return, const std::string& login, const std::string& tableName) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->listIterators(_return, login, tableName);
    }
    ifaces_[i]->listIterators(_return, login, tableName);
    return;
  }

  void listConstraints(std::map<std::string, int32_t> & _return, const std::string& login, const std::string& tableName) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->listConstraints(_return, login, tableName);
    }
    ifaces_[i]->listConstraints(_return, login, tableName);
    return;
  }

  void mergeTablets(const std::string& login, const std::string& tableName, const std::string& startRow, const std::string& endRow) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->mergeTablets(login, tableName, startRow, endRow);
    }
    ifaces_[i]->mergeTablets(login, tableName, startRow, endRow);
  }

  void offlineTable(const std::string& login, const std::string& tableName, const bool wait) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->offlineTable(login, tableName, wait);
    }
    ifaces_[i]->offlineTable(login, tableName, wait);
  }

  void onlineTable(const std::string& login, const std::string& tableName, const bool wait) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->onlineTable(login, tableName, wait);
    }
    ifaces_[i]->onlineTable(login, tableName, wait);
  }

  void removeConstraint(const std::string& login, const std::string& tableName, const int32_t constraint) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->removeConstraint(login, tableName, constraint);
    }
    ifaces_[i]->removeConstraint(login, tableName, constraint);
  }

  void removeIterator(const std::string& login, const std::string& tableName, const std::string& iterName, const std::set<IteratorScope::type> & scopes) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->removeIterator(login, tableName, iterName, scopes);
    }
    ifaces_[i]->removeIterator(login, tableName, iterName, scopes);
  }

  void removeTableProperty(const std::string& login, const std::string& tableName, const std::string& property) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->removeTableProperty(login, tableName, property);
    }
    ifaces_[i]->removeTableProperty(login, tableName, property);
  }

  void renameTable(const std::string& login, const std::string& oldTableName, const std::string& newTableName) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->renameTable(login, oldTableName, newTableName);
    }
    ifaces_[i]->renameTable(login, oldTableName, newTableName);
  }

  void setLocalityGroups(const std::string& login, const std::string& tableName, const std::map<std::string, std::set<std::string> > & groups) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->setLocalityGroups(login, tableName, groups);
    }
    ifaces_[i]->setLocalityGroups(login, tableName, groups);
  }

  void setTableProperty(const std::string& login, const std::string& tableName, const std::string& property, const std::string& value) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->setTableProperty(login, tableName, property, value);
    }
    ifaces_[i]->setTableProperty(login, tableName, property, value);
  }

  void splitRangeByTablets(std::set<Range> & _return, const std::string& login, const std::string& tableName, const Range& range, const int32_t maxSplits) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->splitRangeByTablets(_return, login, tableName, range, maxSplits);
    }
    ifaces_[i]->splitRangeByTablets(_return, login, tableName, range, maxSplits);
    return;
  }

  bool tableExists(const std::string& login, const std::string& tableName) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->tableExists(login, tableName);
    }
    return ifaces_[i]->tableExists(login, tableName);
  }

  void tableIdMap(std::map<std::string, std::string> & _return, const std::string& login) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->tableIdMap(_return, login);
    }
    ifaces_[i]->tableIdMap(_return, login);
    return;
  }

  bool testTableClassLoad(const std::string& login, const std::string& tableName, const std::string& className, const std::string& asTypeName) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->testTableClassLoad(login, tableName, className, asTypeName);
    }
    return ifaces_[i]->testTableClassLoad(login, tableName, className, asTypeName);
  }

  void pingTabletServer(const std::string& login, const std::string& tserver) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->pingTabletServer(login, tserver);
    }
    ifaces_[i]->pingTabletServer(login, tserver);
  }

  void getActiveScans(std::vector<ActiveScan> & _return, const std::string& login, const std::string& tserver) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->getActiveScans(_return, login, tserver);
    }
    ifaces_[i]->getActiveScans(_return, login, tserver);
    return;
  }

  void getActiveCompactions(std::vector<ActiveCompaction> & _return, const std::string& login, const std::string& tserver) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->getActiveCompactions(_return, login, tserver);
    }
    ifaces_[i]->getActiveCompactions(_return, login, tserver);
    return;
  }

  void getSiteConfiguration(std::map<std::string, std::string> & _return, const std::string& login) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->getSiteConfiguration(_return, login);
    }
    ifaces_[i]->getSiteConfiguration(_return, login);
    return;
  }

  void getSystemConfiguration(std::map<std::string, std::string> & _return, const std::string& login) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->getSystemConfiguration(_return, login);
    }
    ifaces_[i]->getSystemConfiguration(_return, login);
    return;
  }

  void getTabletServers(std::vector<std::string> & _return, const std::string& login) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->getTabletServers(_return, login);
    }
    ifaces_[i]->getTabletServers(_return, login);
    return;
  }

  void removeProperty(const std::string& login, const std::string& property) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->removeProperty(login, property);
    }
    ifaces_[i]->removeProperty(login, property);
  }

  void setProperty(const std::string& login, const std::string& property, const std::string& value) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->setProperty(login, property, value);
    }
    ifaces_[i]->setProperty(login, property, value);
  }

  bool testClassLoad(const std::string& login, const std::string& className, const std::string& asTypeName) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->testClassLoad(login, className, asTypeName);
    }
    return ifaces_[i]->testClassLoad(login, className, asTypeName);
  }

  bool authenticateUser(const std::string& login, const std::string& user, const std::map<std::string, std::string> & properties) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->authenticateUser(login, user, properties);
    }
    return ifaces_[i]->authenticateUser(login, user, properties);
  }

  void changeUserAuthorizations(const std::string& login, const std::string& user, const std::set<std::string> & authorizations) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->changeUserAuthorizations(login, user, authorizations);
    }
    ifaces_[i]->changeUserAuthorizations(login, user, authorizations);
  }

  void changeLocalUserPassword(const std::string& login, const std::string& user, const std::string& password) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->changeLocalUserPassword(login, user, password);
    }
    ifaces_[i]->changeLocalUserPassword(login, user, password);
  }

  void createLocalUser(const std::string& login, const std::string& user, const std::string& password) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->createLocalUser(login, user, password);
    }
    ifaces_[i]->createLocalUser(login, user, password);
  }

  void dropLocalUser(const std::string& login, const std::string& user) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->dropLocalUser(login, user);
    }
    ifaces_[i]->dropLocalUser(login, user);
  }

  void getUserAuthorizations(std::vector<std::string> & _return, const std::string& login, const std::string& user) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->getUserAuthorizations(_return, login, user);
    }
    ifaces_[i]->getUserAuthorizations(_return, login, user);
    return;
  }

  void grantSystemPermission(const std::string& login, const std::string& user, const SystemPermission::type perm) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->grantSystemPermission(login, user, perm);
    }
    ifaces_[i]->grantSystemPermission(login, user, perm);
  }

  void grantTablePermission(const std::string& login, const std::string& user, const std::string& table, const TablePermission::type perm) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->grantTablePermission(login, user, table, perm);
    }
    ifaces_[i]->grantTablePermission(login, user, table, perm);
  }

  bool hasSystemPermission(const std::string& login, const std::string& user, const SystemPermission::type perm) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->hasSystemPermission(login, user, perm);
    }
    return ifaces_[i]->hasSystemPermission(login, user, perm);
  }

  bool hasTablePermission(const std::string& login, const std::string& user, const std::string& table, const TablePermission::type perm) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->hasTablePermission(login, user, table, perm);
    }
    return ifaces_[i]->hasTablePermission(login, user, table, perm);
  }

  void listLocalUsers(std::set<std::string> & _return, const std::string& login) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->listLocalUsers(_return, login);
    }
    ifaces_[i]->listLocalUsers(_return, login);
    return;
  }

  void revokeSystemPermission(const std::string& login, const std::string& user, const SystemPermission::type perm) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->revokeSystemPermission(login, user, perm);
    }
    ifaces_[i]->revokeSystemPermission(login, user, perm);
  }

  void revokeTablePermission(const std::string& login, const std::string& user, const std::string& table, const TablePermission::type perm) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->revokeTablePermission(login, user, table, perm);
    }
    ifaces_[i]->revokeTablePermission(login, user, table, perm);
  }

  void grantNamespacePermission(const std::string& login, const std::string& user, const std::string& namespaceName, const NamespacePermission::type perm) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->grantNamespacePermission(login, user, namespaceName, perm);
    }
    ifaces_[i]->grantNamespacePermission(login, user, namespaceName, perm);
  }

  bool hasNamespacePermission(const std::string& login, const std::string& user, const std::string& namespaceName, const NamespacePermission::type perm) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->hasNamespacePermission(login, user, namespaceName, perm);
    }
    return ifaces_[i]->hasNamespacePermission(login, user, namespaceName, perm);
  }

  void revokeNamespacePermission(const std::string& login, const std::string& user, const std::string& namespaceName, const NamespacePermission::type perm) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->revokeNamespacePermission(login, user, namespaceName, perm);
    }
    ifaces_[i]->revokeNamespacePermission(login, user, namespaceName, perm);
  }

  void createBatchScanner(std::string& _return, const std::string& login, const std::string& tableName, const BatchScanOptions& options) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->createBatchScanner(_return, login, tableName, options);
    }
    ifaces_[i]->createBatchScanner(_return, login, tableName, options);
    return;
  }

  void createScanner(std::string& _return, const std::string& login, const std::string& tableName, const ScanOptions& options) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->createScanner(_return, login, tableName, options);
    }
    ifaces_[i]->createScanner(_return, login, tableName, options);
    return;
  }

  bool hasNext(const std::string& scanner) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->hasNext(scanner);
    }
    return ifaces_[i]->hasNext(scanner);
  }

  void nextEntry(KeyValueAndPeek& _return, const std::string& scanner) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->nextEntry(_return, scanner);
    }
    ifaces_[i]->nextEntry(_return, scanner);
    return;
  }

  void nextK(ScanResult& _return, const std::string& scanner, const int32_t k) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->nextK(_return, scanner, k);
    }
    ifaces_[i]->nextK(_return, scanner, k);
    return;
  }

  void closeScanner(const std::string& scanner) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->closeScanner(scanner);
    }
    ifaces_[i]->closeScanner(scanner);
  }

  void updateAndFlush(const std::string& login, const std::string& tableName, const std::map<std::string, std::vector<ColumnUpdate> > & cells) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->updateAndFlush(login, tableName, cells);
    }
    ifaces_[i]->updateAndFlush(login, tableName, cells);
  }

  void createWriter(std::string& _return, const std::string& login, const std::string& tableName, const WriterOptions& opts) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->createWriter(_return, login, tableName, opts);
    }
    ifaces_[i]->createWriter(_return, login, tableName, opts);
    return;
  }

  void update(const std::string& writer, const std::map<std::string, std::vector<ColumnUpdate> > & cells) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->update(writer, cells);
    }
    ifaces_[i]->update(writer, cells);
  }

  void flush(const std::string& writer) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->flush(writer);
    }
    ifaces_[i]->flush(writer);
  }

  void closeWriter(const std::string& writer) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->closeWriter(writer);
    }
    ifaces_[i]->closeWriter(writer);
  }

  ConditionalStatus::type updateRowConditionally(const std::string& login, const std::string& tableName, const std::string& row, const ConditionalUpdates& updates) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->updateRowConditionally(login, tableName, row, updates);
    }
    return ifaces_[i]->updateRowConditionally(login, tableName, row, updates);
  }

  void createConditionalWriter(std::string& _return, const std::string& login, const std::string& tableName, const ConditionalWriterOptions& options) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->createConditionalWriter(_return, login, tableName, options);
    }
    ifaces_[i]->createConditionalWriter(_return, login, tableName, options);
    return;
  }

  void updateRowsConditionally(std::map<std::string, ConditionalStatus::type> & _return, const std::string& conditionalWriter, const std::map<std::string, ConditionalUpdates> & updates) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->updateRowsConditionally(_return, conditionalWriter, updates);
    }
    ifaces_[i]->updateRowsConditionally(_return, conditionalWriter, updates);
    return;
  }

  void closeConditionalWriter(const std::string& conditionalWriter) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->closeConditionalWriter(conditionalWriter);
    }
    ifaces_[i]->closeConditionalWriter(conditionalWriter);
  }

  void getRowRange(Range& _return, const std::string& row) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->getRowRange(_return, row);
    }
    ifaces_[i]->getRowRange(_return, row);
    return;
  }

  void getFollowing(Key& _return, const Key& key, const PartialKey::type part) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->getFollowing(_return, key, part);
    }
    ifaces_[i]->getFollowing(_return, key, part);
    return;
  }

  void systemNamespace(std::string& _return) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->systemNamespace(_return);
    }
    ifaces_[i]->systemNamespace(_return);
    return;
  }

  void defaultNamespace(std::string& _return) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->defaultNamespace(_return);
    }
    ifaces_[i]->defaultNamespace(_return);
    return;
  }

  void listNamespaces(std::vector<std::string> & _return, const std::string& login) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->listNamespaces(_return, login);
    }
    ifaces_[i]->listNamespaces(_return, login);
    return;
  }

  bool namespaceExists(const std::string& login, const std::string& namespaceName) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->namespaceExists(login, namespaceName);
    }
    return ifaces_[i]->namespaceExists(login, namespaceName);
  }

  void createNamespace(const std::string& login, const std::string& namespaceName) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->createNamespace(login, namespaceName);
    }
    ifaces_[i]->createNamespace(login, namespaceName);
  }

  void deleteNamespace(const std::string& login, const std::string& namespaceName) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->deleteNamespace(login, namespaceName);
    }
    ifaces_[i]->deleteNamespace(login, namespaceName);
  }

  void renameNamespace(const std::string& login, const std::string& oldNamespaceName, const std::string& newNamespaceName) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->renameNamespace(login, oldNamespaceName, newNamespaceName);
    }
    ifaces_[i]->renameNamespace(login, oldNamespaceName, newNamespaceName);
  }

  void setNamespaceProperty(const std::string& login, const std::string& namespaceName, const std::string& property, const std::string& value) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->setNamespaceProperty(login, namespaceName, property, value);
    }
    ifaces_[i]->setNamespaceProperty(login, namespaceName, property, value);
  }

  void removeNamespaceProperty(const std::string& login, const std::string& namespaceName, const std::string& property) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->removeNamespaceProperty(login, namespaceName, property);
    }
    ifaces_[i]->removeNamespaceProperty(login, namespaceName, property);
  }

  void getNamespaceProperties(std::map<std::string, std::string> & _return, const std::string& login, const std::string& namespaceName) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->getNamespaceProperties(_return, login, namespaceName);
    }
    ifaces_[i]->getNamespaceProperties(_return, login, namespaceName);
    return;
  }

  void namespaceIdMap(std::map<std::string, std::string> & _return, const std::string& login) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->namespaceIdMap(_return, login);
    }
    ifaces_[i]->namespaceIdMap(_return, login);
    return;
  }

  void attachNamespaceIterator(const std::string& login, const std::string& namespaceName, const IteratorSetting& setting, const std::set<IteratorScope::type> & scopes) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->attachNamespaceIterator(login, namespaceName, setting, scopes);
    }
    ifaces_[i]->attachNamespaceIterator(login, namespaceName, setting, scopes);
  }

  void removeNamespaceIterator(const std::string& login, const std::string& namespaceName, const std::string& name, const std::set<IteratorScope::type> & scopes) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->removeNamespaceIterator(login, namespaceName, name, scopes);
    }
    ifaces_[i]->removeNamespaceIterator(login, namespaceName, name, scopes);
  }

  void getNamespaceIteratorSetting(IteratorSetting& _return, const std::string& login, const std::string& namespaceName, const std::string& name, const IteratorScope::type scope) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->getNamespaceIteratorSetting(_return, login, namespaceName, name, scope);
    }
    ifaces_[i]->getNamespaceIteratorSetting(_return, login, namespaceName, name, scope);
    return;
  }

  void listNamespaceIterators(std::map<std::string, std::set<IteratorScope::type> > & _return, const std::string& login, const std::string& namespaceName) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->listNamespaceIterators(_return, login, namespaceName);
    }
    ifaces_[i]->listNamespaceIterators(_return, login, namespaceName);
    return;
  }

  void checkNamespaceIteratorConflicts(const std::string& login, const std::string& namespaceName, const IteratorSetting& setting, const std::set<IteratorScope::type> & scopes) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->checkNamespaceIteratorConflicts(login, namespaceName, setting, scopes);
    }
    ifaces_[i]->checkNamespaceIteratorConflicts(login, namespaceName, setting, scopes);
  }

  int32_t addNamespaceConstraint(const std::string& login, const std::string& namespaceName, const std::string& constraintClassName) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->addNamespaceConstraint(login, namespaceName, constraintClassName);
    }
    return ifaces_[i]->addNamespaceConstraint(login, namespaceName, constraintClassName);
  }

  void removeNamespaceConstraint(const std::string& login, const std::string& namespaceName, const int32_t id) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->removeNamespaceConstraint(login, namespaceName, id);
    }
    ifaces_[i]->removeNamespaceConstraint(login, namespaceName, id);
  }

  void listNamespaceConstraints(std::map<std::string, int32_t> & _return, const std::string& login, const std::string& namespaceName) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->listNamespaceConstraints(_return, login, namespaceName);
    }
    ifaces_[i]->listNamespaceConstraints(_return, login, namespaceName);
    return;
  }

  bool testNamespaceClassLoad(const std::string& login, const std::string& namespaceName, const std::string& className, const std::string& asTypeName) {
    size_t sz = ifaces_.size();
    size_t i = 0;
    for (; i < (sz - 1); ++i) {
      ifaces_[i]->testNamespaceClassLoad(login, namespaceName, className, asTypeName);
    }
    return ifaces_[i]->testNamespaceClassLoad(login, namespaceName, className, asTypeName);
  }

};

// The 'concurrent' client is a thread safe client that correctly handles
// out of order responses.  It is slower than the regular client, so should
// only be used when you need to share a connection among multiple threads
class AccumuloProxyConcurrentClient : virtual public AccumuloProxyIf {
 public:
  AccumuloProxyConcurrentClient(boost::shared_ptr< ::apache::thrift::protocol::TProtocol> prot) {
    setProtocol(prot);
  }
  AccumuloProxyConcurrentClient(boost::shared_ptr< ::apache::thrift::protocol::TProtocol> iprot, boost::shared_ptr< ::apache::thrift::protocol::TProtocol> oprot) {
    setProtocol(iprot,oprot);
  }
 private:
  void setProtocol(boost::shared_ptr< ::apache::thrift::protocol::TProtocol> prot) {
  setProtocol(prot,prot);
  }
  void setProtocol(boost::shared_ptr< ::apache::thrift::protocol::TProtocol> iprot, boost::shared_ptr< ::apache::thrift::protocol::TProtocol> oprot) {
    piprot_=iprot;
    poprot_=oprot;
    iprot_ = iprot.get();
    oprot_ = oprot.get();
  }
 public:
  boost::shared_ptr< ::apache::thrift::protocol::TProtocol> getInputProtocol() {
    return piprot_;
  }
  boost::shared_ptr< ::apache::thrift::protocol::TProtocol> getOutputProtocol() {
    return poprot_;
  }
  void login(std::string& _return, const std::string& principal, const std::map<std::string, std::string> & loginProperties);
  int32_t send_login(const std::string& principal, const std::map<std::string, std::string> & loginProperties);
  void recv_login(std::string& _return, const int32_t seqid);
  int32_t addConstraint(const std::string& login, const std::string& tableName, const std::string& constraintClassName);
  int32_t send_addConstraint(const std::string& login, const std::string& tableName, const std::string& constraintClassName);
  int32_t recv_addConstraint(const int32_t seqid);
  void addSplits(const std::string& login, const std::string& tableName, const std::set<std::string> & splits);
  int32_t send_addSplits(const std::string& login, const std::string& tableName, const std::set<std::string> & splits);
  void recv_addSplits(const int32_t seqid);
  void attachIterator(const std::string& login, const std::string& tableName, const IteratorSetting& setting, const std::set<IteratorScope::type> & scopes);
  int32_t send_attachIterator(const std::string& login, const std::string& tableName, const IteratorSetting& setting, const std::set<IteratorScope::type> & scopes);
  void recv_attachIterator(const int32_t seqid);
  void checkIteratorConflicts(const std::string& login, const std::string& tableName, const IteratorSetting& setting, const std::set<IteratorScope::type> & scopes);
  int32_t send_checkIteratorConflicts(const std::string& login, const std::string& tableName, const IteratorSetting& setting, const std::set<IteratorScope::type> & scopes);
  void recv_checkIteratorConflicts(const int32_t seqid);
  void clearLocatorCache(const std::string& login, const std::string& tableName);
  int32_t send_clearLocatorCache(const std::string& login, const std::string& tableName);
  void recv_clearLocatorCache(const int32_t seqid);
  void cloneTable(const std::string& login, const std::string& tableName, const std::string& newTableName, const bool flush, const std::map<std::string, std::string> & propertiesToSet, const std::set<std::string> & propertiesToExclude);
  int32_t send_cloneTable(const std::string& login, const std::string& tableName, const std::string& newTableName, const bool flush, const std::map<std::string, std::string> & propertiesToSet, const std::set<std::string> & propertiesToExclude);
  void recv_cloneTable(const int32_t seqid);
  void compactTable(const std::string& login, const std::string& tableName, const std::string& startRow, const std::string& endRow, const std::vector<IteratorSetting> & iterators, const bool flush, const bool wait, const CompactionStrategyConfig& compactionStrategy);
  int32_t send_compactTable(const std::string& login, const std::string& tableName, const std::string& startRow, const std::string& endRow, const std::vector<IteratorSetting> & iterators, const bool flush, const bool wait, const CompactionStrategyConfig& compactionStrategy);
  void recv_compactTable(const int32_t seqid);
  void cancelCompaction(const std::string& login, const std::string& tableName);
  int32_t send_cancelCompaction(const std::string& login, const std::string& tableName);
  void recv_cancelCompaction(const int32_t seqid);
  void createTable(const std::string& login, const std::string& tableName, const bool versioningIter, const TimeType::type type);
  int32_t send_createTable(const std::string& login, const std::string& tableName, const bool versioningIter, const TimeType::type type);
  void recv_createTable(const int32_t seqid);
  void deleteTable(const std::string& login, const std::string& tableName);
  int32_t send_deleteTable(const std::string& login, const std::string& tableName);
  void recv_deleteTable(const int32_t seqid);
  void deleteRows(const std::string& login, const std::string& tableName, const std::string& startRow, const std::string& endRow);
  int32_t send_deleteRows(const std::string& login, const std::string& tableName, const std::string& startRow, const std::string& endRow);
  void recv_deleteRows(const int32_t seqid);
  void exportTable(const std::string& login, const std::string& tableName, const std::string& exportDir);
  int32_t send_exportTable(const std::string& login, const std::string& tableName, const std::string& exportDir);
  void recv_exportTable(const int32_t seqid);
  void flushTable(const std::string& login, const std::string& tableName, const std::string& startRow, const std::string& endRow, const bool wait);
  int32_t send_flushTable(const std::string& login, const std::string& tableName, const std::string& startRow, const std::string& endRow, const bool wait);
  void recv_flushTable(const int32_t seqid);
  void getDiskUsage(std::vector<DiskUsage> & _return, const std::string& login, const std::set<std::string> & tables);
  int32_t send_getDiskUsage(const std::string& login, const std::set<std::string> & tables);
  void recv_getDiskUsage(std::vector<DiskUsage> & _return, const int32_t seqid);
  void getLocalityGroups(std::map<std::string, std::set<std::string> > & _return, const std::string& login, const std::string& tableName);
  int32_t send_getLocalityGroups(const std::string& login, const std::string& tableName);
  void recv_getLocalityGroups(std::map<std::string, std::set<std::string> > & _return, const int32_t seqid);
  void getIteratorSetting(IteratorSetting& _return, const std::string& login, const std::string& tableName, const std::string& iteratorName, const IteratorScope::type scope);
  int32_t send_getIteratorSetting(const std::string& login, const std::string& tableName, const std::string& iteratorName, const IteratorScope::type scope);
  void recv_getIteratorSetting(IteratorSetting& _return, const int32_t seqid);
  void getMaxRow(std::string& _return, const std::string& login, const std::string& tableName, const std::set<std::string> & auths, const std::string& startRow, const bool startInclusive, const std::string& endRow, const bool endInclusive);
  int32_t send_getMaxRow(const std::string& login, const std::string& tableName, const std::set<std::string> & auths, const std::string& startRow, const bool startInclusive, const std::string& endRow, const bool endInclusive);
  void recv_getMaxRow(std::string& _return, const int32_t seqid);
  void getTableProperties(std::map<std::string, std::string> & _return, const std::string& login, const std::string& tableName);
  int32_t send_getTableProperties(const std::string& login, const std::string& tableName);
  void recv_getTableProperties(std::map<std::string, std::string> & _return, const int32_t seqid);
  void importDirectory(const std::string& login, const std::string& tableName, const std::string& importDir, const std::string& failureDir, const bool setTime);
  int32_t send_importDirectory(const std::string& login, const std::string& tableName, const std::string& importDir, const std::string& failureDir, const bool setTime);
  void recv_importDirectory(const int32_t seqid);
  void importTable(const std::string& login, const std::string& tableName, const std::string& importDir);
  int32_t send_importTable(const std::string& login, const std::string& tableName, const std::string& importDir);
  void recv_importTable(const int32_t seqid);
  void listSplits(std::vector<std::string> & _return, const std::string& login, const std::string& tableName, const int32_t maxSplits);
  int32_t send_listSplits(const std::string& login, const std::string& tableName, const int32_t maxSplits);
  void recv_listSplits(std::vector<std::string> & _return, const int32_t seqid);
  void listTables(std::set<std::string> & _return, const std::string& login);
  int32_t send_listTables(const std::string& login);
  void recv_listTables(std::set<std::string> & _return, const int32_t seqid);
  void listIterators(std::map<std::string, std::set<IteratorScope::type> > & _return, const std::string& login, const std::string& tableName);
  int32_t send_listIterators(const std::string& login, const std::string& tableName);
  void recv_listIterators(std::map<std::string, std::set<IteratorScope::type> > & _return, const int32_t seqid);
  void listConstraints(std::map<std::string, int32_t> & _return, const std::string& login, const std::string& tableName);
  int32_t send_listConstraints(const std::string& login, const std::string& tableName);
  void recv_listConstraints(std::map<std::string, int32_t> & _return, const int32_t seqid);
  void mergeTablets(const std::string& login, const std::string& tableName, const std::string& startRow, const std::string& endRow);
  int32_t send_mergeTablets(const std::string& login, const std::string& tableName, const std::string& startRow, const std::string& endRow);
  void recv_mergeTablets(const int32_t seqid);
  void offlineTable(const std::string& login, const std::string& tableName, const bool wait);
  int32_t send_offlineTable(const std::string& login, const std::string& tableName, const bool wait);
  void recv_offlineTable(const int32_t seqid);
  void onlineTable(const std::string& login, const std::string& tableName, const bool wait);
  int32_t send_onlineTable(const std::string& login, const std::string& tableName, const bool wait);
  void recv_onlineTable(const int32_t seqid);
  void removeConstraint(const std::string& login, const std::string& tableName, const int32_t constraint);
  int32_t send_removeConstraint(const std::string& login, const std::string& tableName, const int32_t constraint);
  void recv_removeConstraint(const int32_t seqid);
  void removeIterator(const std::string& login, const std::string& tableName, const std::string& iterName, const std::set<IteratorScope::type> & scopes);
  int32_t send_removeIterator(const std::string& login, const std::string& tableName, const std::string& iterName, const std::set<IteratorScope::type> & scopes);
  void recv_removeIterator(const int32_t seqid);
  void removeTableProperty(const std::string& login, const std::string& tableName, const std::string& property);
  int32_t send_removeTableProperty(const std::string& login, const std::string& tableName, const std::string& property);
  void recv_removeTableProperty(const int32_t seqid);
  void renameTable(const std::string& login, const std::string& oldTableName, const std::string& newTableName);
  int32_t send_renameTable(const std::string& login, const std::string& oldTableName, const std::string& newTableName);
  void recv_renameTable(const int32_t seqid);
  void setLocalityGroups(const std::string& login, const std::string& tableName, const std::map<std::string, std::set<std::string> > & groups);
  int32_t send_setLocalityGroups(const std::string& login, const std::string& tableName, const std::map<std::string, std::set<std::string> > & groups);
  void recv_setLocalityGroups(const int32_t seqid);
  void setTableProperty(const std::string& login, const std::string& tableName, const std::string& property, const std::string& value);
  int32_t send_setTableProperty(const std::string& login, const std::string& tableName, const std::string& property, const std::string& value);
  void recv_setTableProperty(const int32_t seqid);
  void splitRangeByTablets(std::set<Range> & _return, const std::string& login, const std::string& tableName, const Range& range, const int32_t maxSplits);
  int32_t send_splitRangeByTablets(const std::string& login, const std::string& tableName, const Range& range, const int32_t maxSplits);
  void recv_splitRangeByTablets(std::set<Range> & _return, const int32_t seqid);
  bool tableExists(const std::string& login, const std::string& tableName);
  int32_t send_tableExists(const std::string& login, const std::string& tableName);
  bool recv_tableExists(const int32_t seqid);
  void tableIdMap(std::map<std::string, std::string> & _return, const std::string& login);
  int32_t send_tableIdMap(const std::string& login);
  void recv_tableIdMap(std::map<std::string, std::string> & _return, const int32_t seqid);
  bool testTableClassLoad(const std::string& login, const std::string& tableName, const std::string& className, const std::string& asTypeName);
  int32_t send_testTableClassLoad(const std::string& login, const std::string& tableName, const std::string& className, const std::string& asTypeName);
  bool recv_testTableClassLoad(const int32_t seqid);
  void pingTabletServer(const std::string& login, const std::string& tserver);
  int32_t send_pingTabletServer(const std::string& login, const std::string& tserver);
  void recv_pingTabletServer(const int32_t seqid);
  void getActiveScans(std::vector<ActiveScan> & _return, const std::string& login, const std::string& tserver);
  int32_t send_getActiveScans(const std::string& login, const std::string& tserver);
  void recv_getActiveScans(std::vector<ActiveScan> & _return, const int32_t seqid);
  void getActiveCompactions(std::vector<ActiveCompaction> & _return, const std::string& login, const std::string& tserver);
  int32_t send_getActiveCompactions(const std::string& login, const std::string& tserver);
  void recv_getActiveCompactions(std::vector<ActiveCompaction> & _return, const int32_t seqid);
  void getSiteConfiguration(std::map<std::string, std::string> & _return, const std::string& login);
  int32_t send_getSiteConfiguration(const std::string& login);
  void recv_getSiteConfiguration(std::map<std::string, std::string> & _return, const int32_t seqid);
  void getSystemConfiguration(std::map<std::string, std::string> & _return, const std::string& login);
  int32_t send_getSystemConfiguration(const std::string& login);
  void recv_getSystemConfiguration(std::map<std::string, std::string> & _return, const int32_t seqid);
  void getTabletServers(std::vector<std::string> & _return, const std::string& login);
  int32_t send_getTabletServers(const std::string& login);
  void recv_getTabletServers(std::vector<std::string> & _return, const int32_t seqid);
  void removeProperty(const std::string& login, const std::string& property);
  int32_t send_removeProperty(const std::string& login, const std::string& property);
  void recv_removeProperty(const int32_t seqid);
  void setProperty(const std::string& login, const std::string& property, const std::string& value);
  int32_t send_setProperty(const std::string& login, const std::string& property, const std::string& value);
  void recv_setProperty(const int32_t seqid);
  bool testClassLoad(const std::string& login, const std::string& className, const std::string& asTypeName);
  int32_t send_testClassLoad(const std::string& login, const std::string& className, const std::string& asTypeName);
  bool recv_testClassLoad(const int32_t seqid);
  bool authenticateUser(const std::string& login, const std::string& user, const std::map<std::string, std::string> & properties);
  int32_t send_authenticateUser(const std::string& login, const std::string& user, const std::map<std::string, std::string> & properties);
  bool recv_authenticateUser(const int32_t seqid);
  void changeUserAuthorizations(const std::string& login, const std::string& user, const std::set<std::string> & authorizations);
  int32_t send_changeUserAuthorizations(const std::string& login, const std::string& user, const std::set<std::string> & authorizations);
  void recv_changeUserAuthorizations(const int32_t seqid);
  void changeLocalUserPassword(const std::string& login, const std::string& user, const std::string& password);
  int32_t send_changeLocalUserPassword(const std::string& login, const std::string& user, const std::string& password);
  void recv_changeLocalUserPassword(const int32_t seqid);
  void createLocalUser(const std::string& login, const std::string& user, const std::string& password);
  int32_t send_createLocalUser(const std::string& login, const std::string& user, const std::string& password);
  void recv_createLocalUser(const int32_t seqid);
  void dropLocalUser(const std::string& login, const std::string& user);
  int32_t send_dropLocalUser(const std::string& login, const std::string& user);
  void recv_dropLocalUser(const int32_t seqid);
  void getUserAuthorizations(std::vector<std::string> & _return, const std::string& login, const std::string& user);
  int32_t send_getUserAuthorizations(const std::string& login, const std::string& user);
  void recv_getUserAuthorizations(std::vector<std::string> & _return, const int32_t seqid);
  void grantSystemPermission(const std::string& login, const std::string& user, const SystemPermission::type perm);
  int32_t send_grantSystemPermission(const std::string& login, const std::string& user, const SystemPermission::type perm);
  void recv_grantSystemPermission(const int32_t seqid);
  void grantTablePermission(const std::string& login, const std::string& user, const std::string& table, const TablePermission::type perm);
  int32_t send_grantTablePermission(const std::string& login, const std::string& user, const std::string& table, const TablePermission::type perm);
  void recv_grantTablePermission(const int32_t seqid);
  bool hasSystemPermission(const std::string& login, const std::string& user, const SystemPermission::type perm);
  int32_t send_hasSystemPermission(const std::string& login, const std::string& user, const SystemPermission::type perm);
  bool recv_hasSystemPermission(const int32_t seqid);
  bool hasTablePermission(const std::string& login, const std::string& user, const std::string& table, const TablePermission::type perm);
  int32_t send_hasTablePermission(const std::string& login, const std::string& user, const std::string& table, const TablePermission::type perm);
  bool recv_hasTablePermission(const int32_t seqid);
  void listLocalUsers(std::set<std::string> & _return, const std::string& login);
  int32_t send_listLocalUsers(const std::string& login);
  void recv_listLocalUsers(std::set<std::string> & _return, const int32_t seqid);
  void revokeSystemPermission(const std::string& login, const std::string& user, const SystemPermission::type perm);
  int32_t send_revokeSystemPermission(const std::string& login, const std::string& user, const SystemPermission::type perm);
  void recv_revokeSystemPermission(const int32_t seqid);
  void revokeTablePermission(const std::string& login, const std::string& user, const std::string& table, const TablePermission::type perm);
  int32_t send_revokeTablePermission(const std::string& login, const std::string& user, const std::string& table, const TablePermission::type perm);
  void recv_revokeTablePermission(const int32_t seqid);
  void grantNamespacePermission(const std::string& login, const std::string& user, const std::string& namespaceName, const NamespacePermission::type perm);
  int32_t send_grantNamespacePermission(const std::string& login, const std::string& user, const std::string& namespaceName, const NamespacePermission::type perm);
  void recv_grantNamespacePermission(const int32_t seqid);
  bool hasNamespacePermission(const std::string& login, const std::string& user, const std::string& namespaceName, const NamespacePermission::type perm);
  int32_t send_hasNamespacePermission(const std::string& login, const std::string& user, const std::string& namespaceName, const NamespacePermission::type perm);
  bool recv_hasNamespacePermission(const int32_t seqid);
  void revokeNamespacePermission(const std::string& login, const std::string& user, const std::string& namespaceName, const NamespacePermission::type perm);
  int32_t send_revokeNamespacePermission(const std::string& login, const std::string& user, const std::string& namespaceName, const NamespacePermission::type perm);
  void recv_revokeNamespacePermission(const int32_t seqid);
  void createBatchScanner(std::string& _return, const std::string& login, const std::string& tableName, const BatchScanOptions& options);
  int32_t send_createBatchScanner(const std::string& login, const std::string& tableName, const BatchScanOptions& options);
  void recv_createBatchScanner(std::string& _return, const int32_t seqid);
  void createScanner(std::string& _return, const std::string& login, const std::string& tableName, const ScanOptions& options);
  int32_t send_createScanner(const std::string& login, const std::string& tableName, const ScanOptions& options);
  void recv_createScanner(std::string& _return, const int32_t seqid);
  bool hasNext(const std::string& scanner);
  int32_t send_hasNext(const std::string& scanner);
  bool recv_hasNext(const int32_t seqid);
  void nextEntry(KeyValueAndPeek& _return, const std::string& scanner);
  int32_t send_nextEntry(const std::string& scanner);
  void recv_nextEntry(KeyValueAndPeek& _return, const int32_t seqid);
  void nextK(ScanResult& _return, const std::string& scanner, const int32_t k);
  int32_t send_nextK(const std::string& scanner, const int32_t k);
  void recv_nextK(ScanResult& _return, const int32_t seqid);
  void closeScanner(const std::string& scanner);
  int32_t send_closeScanner(const std::string& scanner);
  void recv_closeScanner(const int32_t seqid);
  void updateAndFlush(const std::string& login, const std::string& tableName, const std::map<std::string, std::vector<ColumnUpdate> > & cells);
  int32_t send_updateAndFlush(const std::string& login, const std::string& tableName, const std::map<std::string, std::vector<ColumnUpdate> > & cells);
  void recv_updateAndFlush(const int32_t seqid);
  void createWriter(std::string& _return, const std::string& login, const std::string& tableName, const WriterOptions& opts);
  int32_t send_createWriter(const std::string& login, const std::string& tableName, const WriterOptions& opts);
  void recv_createWriter(std::string& _return, const int32_t seqid);
  void update(const std::string& writer, const std::map<std::string, std::vector<ColumnUpdate> > & cells);
  void send_update(const std::string& writer, const std::map<std::string, std::vector<ColumnUpdate> > & cells);
  void flush(const std::string& writer);
  int32_t send_flush(const std::string& writer);
  void recv_flush(const int32_t seqid);
  void closeWriter(const std::string& writer);
  int32_t send_closeWriter(const std::string& writer);
  void recv_closeWriter(const int32_t seqid);
  ConditionalStatus::type updateRowConditionally(const std::string& login, const std::string& tableName, const std::string& row, const ConditionalUpdates& updates);
  int32_t send_updateRowConditionally(const std::string& login, const std::string& tableName, const std::string& row, const ConditionalUpdates& updates);
  ConditionalStatus::type recv_updateRowConditionally(const int32_t seqid);
  void createConditionalWriter(std::string& _return, const std::string& login, const std::string& tableName, const ConditionalWriterOptions& options);
  int32_t send_createConditionalWriter(const std::string& login, const std::string& tableName, const ConditionalWriterOptions& options);
  void recv_createConditionalWriter(std::string& _return, const int32_t seqid);
  void updateRowsConditionally(std::map<std::string, ConditionalStatus::type> & _return, const std::string& conditionalWriter, const std::map<std::string, ConditionalUpdates> & updates);
  int32_t send_updateRowsConditionally(const std::string& conditionalWriter, const std::map<std::string, ConditionalUpdates> & updates);
  void recv_updateRowsConditionally(std::map<std::string, ConditionalStatus::type> & _return, const int32_t seqid);
  void closeConditionalWriter(const std::string& conditionalWriter);
  int32_t send_closeConditionalWriter(const std::string& conditionalWriter);
  void recv_closeConditionalWriter(const int32_t seqid);
  void getRowRange(Range& _return, const std::string& row);
  int32_t send_getRowRange(const std::string& row);
  void recv_getRowRange(Range& _return, const int32_t seqid);
  void getFollowing(Key& _return, const Key& key, const PartialKey::type part);
  int32_t send_getFollowing(const Key& key, const PartialKey::type part);
  void recv_getFollowing(Key& _return, const int32_t seqid);
  void systemNamespace(std::string& _return);
  int32_t send_systemNamespace();
  void recv_systemNamespace(std::string& _return, const int32_t seqid);
  void defaultNamespace(std::string& _return);
  int32_t send_defaultNamespace();
  void recv_defaultNamespace(std::string& _return, const int32_t seqid);
  void listNamespaces(std::vector<std::string> & _return, const std::string& login);
  int32_t send_listNamespaces(const std::string& login);
  void recv_listNamespaces(std::vector<std::string> & _return, const int32_t seqid);
  bool namespaceExists(const std::string& login, const std::string& namespaceName);
  int32_t send_namespaceExists(const std::string& login, const std::string& namespaceName);
  bool recv_namespaceExists(const int32_t seqid);
  void createNamespace(const std::string& login, const std::string& namespaceName);
  int32_t send_createNamespace(const std::string& login, const std::string& namespaceName);
  void recv_createNamespace(const int32_t seqid);
  void deleteNamespace(const std::string& login, const std::string& namespaceName);
  int32_t send_deleteNamespace(const std::string& login, const std::string& namespaceName);
  void recv_deleteNamespace(const int32_t seqid);
  void renameNamespace(const std::string& login, const std::string& oldNamespaceName, const std::string& newNamespaceName);
  int32_t send_renameNamespace(const std::string& login, const std::string& oldNamespaceName, const std::string& newNamespaceName);
  void recv_renameNamespace(const int32_t seqid);
  void setNamespaceProperty(const std::string& login, const std::string& namespaceName, const std::string& property, const std::string& value);
  int32_t send_setNamespaceProperty(const std::string& login, const std::string& namespaceName, const std::string& property, const std::string& value);
  void recv_setNamespaceProperty(const int32_t seqid);
  void removeNamespaceProperty(const std::string& login, const std::string& namespaceName, const std::string& property);
  int32_t send_removeNamespaceProperty(const std::string& login, const std::string& namespaceName, const std::string& property);
  void recv_removeNamespaceProperty(const int32_t seqid);
  void getNamespaceProperties(std::map<std::string, std::string> & _return, const std::string& login, const std::string& namespaceName);
  int32_t send_getNamespaceProperties(const std::string& login, const std::string& namespaceName);
  void recv_getNamespaceProperties(std::map<std::string, std::string> & _return, const int32_t seqid);
  void namespaceIdMap(std::map<std::string, std::string> & _return, const std::string& login);
  int32_t send_namespaceIdMap(const std::string& login);
  void recv_namespaceIdMap(std::map<std::string, std::string> & _return, const int32_t seqid);
  void attachNamespaceIterator(const std::string& login, const std::string& namespaceName, const IteratorSetting& setting, const std::set<IteratorScope::type> & scopes);
  int32_t send_attachNamespaceIterator(const std::string& login, const std::string& namespaceName, const IteratorSetting& setting, const std::set<IteratorScope::type> & scopes);
  void recv_attachNamespaceIterator(const int32_t seqid);
  void removeNamespaceIterator(const std::string& login, const std::string& namespaceName, const std::string& name, const std::set<IteratorScope::type> & scopes);
  int32_t send_removeNamespaceIterator(const std::string& login, const std::string& namespaceName, const std::string& name, const std::set<IteratorScope::type> & scopes);
  void recv_removeNamespaceIterator(const int32_t seqid);
  void getNamespaceIteratorSetting(IteratorSetting& _return, const std::string& login, const std::string& namespaceName, const std::string& name, const IteratorScope::type scope);
  int32_t send_getNamespaceIteratorSetting(const std::string& login, const std::string& namespaceName, const std::string& name, const IteratorScope::type scope);
  void recv_getNamespaceIteratorSetting(IteratorSetting& _return, const int32_t seqid);
  void listNamespaceIterators(std::map<std::string, std::set<IteratorScope::type> > & _return, const std::string& login, const std::string& namespaceName);
  int32_t send_listNamespaceIterators(const std::string& login, const std::string& namespaceName);
  void recv_listNamespaceIterators(std::map<std::string, std::set<IteratorScope::type> > & _return, const int32_t seqid);
  void checkNamespaceIteratorConflicts(const std::string& login, const std::string& namespaceName, const IteratorSetting& setting, const std::set<IteratorScope::type> & scopes);
  int32_t send_checkNamespaceIteratorConflicts(const std::string& login, const std::string& namespaceName, const IteratorSetting& setting, const std::set<IteratorScope::type> & scopes);
  void recv_checkNamespaceIteratorConflicts(const int32_t seqid);
  int32_t addNamespaceConstraint(const std::string& login, const std::string& namespaceName, const std::string& constraintClassName);
  int32_t send_addNamespaceConstraint(const std::string& login, const std::string& namespaceName, const std::string& constraintClassName);
  int32_t recv_addNamespaceConstraint(const int32_t seqid);
  void removeNamespaceConstraint(const std::string& login, const std::string& namespaceName, const int32_t id);
  int32_t send_removeNamespaceConstraint(const std::string& login, const std::string& namespaceName, const int32_t id);
  void recv_removeNamespaceConstraint(const int32_t seqid);
  void listNamespaceConstraints(std::map<std::string, int32_t> & _return, const std::string& login, const std::string& namespaceName);
  int32_t send_listNamespaceConstraints(const std::string& login, const std::string& namespaceName);
  void recv_listNamespaceConstraints(std::map<std::string, int32_t> & _return, const int32_t seqid);
  bool testNamespaceClassLoad(const std::string& login, const std::string& namespaceName, const std::string& className, const std::string& asTypeName);
  int32_t send_testNamespaceClassLoad(const std::string& login, const std::string& namespaceName, const std::string& className, const std::string& asTypeName);
  bool recv_testNamespaceClassLoad(const int32_t seqid);
 protected:
  boost::shared_ptr< ::apache::thrift::protocol::TProtocol> piprot_;
  boost::shared_ptr< ::apache::thrift::protocol::TProtocol> poprot_;
  ::apache::thrift::protocol::TProtocol* iprot_;
  ::apache::thrift::protocol::TProtocol* oprot_;
  ::apache::thrift::async::TConcurrentClientSyncInfo sync_;
};

#ifdef _WIN32
  #pragma warning( pop )
#endif

} // namespace

#endif
