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

/**
 * Autogenerated by Thrift Compiler (0.10.0)
 *
 * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
 *  @generated
 */
package org.apache.airavata.service.profile.tenant.cpi;

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

  public interface Iface extends org.apache.airavata.base.api.BaseAPI.Iface {

    /**
     * Return the airavataInternalGatewayId assigned to given gateway.
     * 
     * @param authzToken
     * @param gateway
     */
    public java.lang.String addGateway(org.apache.airavata.model.security.AuthzToken authzToken, org.apache.airavata.model.workspace.Gateway gateway) throws org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    public boolean updateGateway(org.apache.airavata.model.security.AuthzToken authzToken, org.apache.airavata.model.workspace.Gateway updatedGateway) throws org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    public org.apache.airavata.model.workspace.Gateway getGateway(org.apache.airavata.model.security.AuthzToken authzToken, java.lang.String airavataInternalGatewayId) throws org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    public boolean deleteGateway(org.apache.airavata.model.security.AuthzToken authzToken, java.lang.String airavataInternalGatewayId, java.lang.String gatewayId) throws org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    public java.util.List<org.apache.airavata.model.workspace.Gateway> getAllGateways(org.apache.airavata.model.security.AuthzToken authzToken) throws org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    public boolean isGatewayExist(org.apache.airavata.model.security.AuthzToken authzToken, java.lang.String gatewayId) throws org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    public java.util.List<org.apache.airavata.model.workspace.Gateway> getAllGatewaysForUser(org.apache.airavata.model.security.AuthzToken authzToken, java.lang.String requesterUsername) throws org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

  }

  public interface AsyncIface extends org.apache.airavata.base.api.BaseAPI .AsyncIface {

    public void addGateway(org.apache.airavata.model.security.AuthzToken authzToken, org.apache.airavata.model.workspace.Gateway gateway, org.apache.thrift.async.AsyncMethodCallback<java.lang.String> resultHandler) throws org.apache.thrift.TException;

    public void updateGateway(org.apache.airavata.model.security.AuthzToken authzToken, org.apache.airavata.model.workspace.Gateway updatedGateway, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException;

    public void getGateway(org.apache.airavata.model.security.AuthzToken authzToken, java.lang.String airavataInternalGatewayId, org.apache.thrift.async.AsyncMethodCallback<org.apache.airavata.model.workspace.Gateway> resultHandler) throws org.apache.thrift.TException;

    public void deleteGateway(org.apache.airavata.model.security.AuthzToken authzToken, java.lang.String airavataInternalGatewayId, java.lang.String gatewayId, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException;

    public void getAllGateways(org.apache.airavata.model.security.AuthzToken authzToken, org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.model.workspace.Gateway>> resultHandler) throws org.apache.thrift.TException;

    public void isGatewayExist(org.apache.airavata.model.security.AuthzToken authzToken, java.lang.String gatewayId, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException;

    public void getAllGatewaysForUser(org.apache.airavata.model.security.AuthzToken authzToken, java.lang.String requesterUsername, org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.model.workspace.Gateway>> resultHandler) throws org.apache.thrift.TException;

  }

  public static class Client extends org.apache.airavata.base.api.BaseAPI.Client implements Iface {
    public static class Factory implements org.apache.thrift.TServiceClientFactory<Client> {
      public Factory() {}
      public Client getClient(org.apache.thrift.protocol.TProtocol prot) {
        return new Client(prot);
      }
      public Client getClient(org.apache.thrift.protocol.TProtocol iprot, org.apache.thrift.protocol.TProtocol oprot) {
        return new Client(iprot, oprot);
      }
    }

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

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

    public java.lang.String addGateway(org.apache.airavata.model.security.AuthzToken authzToken, org.apache.airavata.model.workspace.Gateway gateway) throws org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_addGateway(authzToken, gateway);
      return recv_addGateway();
    }

    public void send_addGateway(org.apache.airavata.model.security.AuthzToken authzToken, org.apache.airavata.model.workspace.Gateway gateway) throws org.apache.thrift.TException
    {
      addGateway_args args = new addGateway_args();
      args.setAuthzToken(authzToken);
      args.setGateway(gateway);
      sendBase("addGateway", args);
    }

    public java.lang.String recv_addGateway() throws org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      addGateway_result result = new addGateway_result();
      receiveBase(result, "addGateway");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.tpe != null) {
        throw result.tpe;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "addGateway failed: unknown result");
    }

    public boolean updateGateway(org.apache.airavata.model.security.AuthzToken authzToken, org.apache.airavata.model.workspace.Gateway updatedGateway) throws org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_updateGateway(authzToken, updatedGateway);
      return recv_updateGateway();
    }

    public void send_updateGateway(org.apache.airavata.model.security.AuthzToken authzToken, org.apache.airavata.model.workspace.Gateway updatedGateway) throws org.apache.thrift.TException
    {
      updateGateway_args args = new updateGateway_args();
      args.setAuthzToken(authzToken);
      args.setUpdatedGateway(updatedGateway);
      sendBase("updateGateway", args);
    }

    public boolean recv_updateGateway() throws org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      updateGateway_result result = new updateGateway_result();
      receiveBase(result, "updateGateway");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.tpe != null) {
        throw result.tpe;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "updateGateway failed: unknown result");
    }

    public org.apache.airavata.model.workspace.Gateway getGateway(org.apache.airavata.model.security.AuthzToken authzToken, java.lang.String airavataInternalGatewayId) throws org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_getGateway(authzToken, airavataInternalGatewayId);
      return recv_getGateway();
    }

    public void send_getGateway(org.apache.airavata.model.security.AuthzToken authzToken, java.lang.String airavataInternalGatewayId) throws org.apache.thrift.TException
    {
      getGateway_args args = new getGateway_args();
      args.setAuthzToken(authzToken);
      args.setAiravataInternalGatewayId(airavataInternalGatewayId);
      sendBase("getGateway", args);
    }

    public org.apache.airavata.model.workspace.Gateway recv_getGateway() throws org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      getGateway_result result = new getGateway_result();
      receiveBase(result, "getGateway");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.tpe != null) {
        throw result.tpe;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getGateway failed: unknown result");
    }

    public boolean deleteGateway(org.apache.airavata.model.security.AuthzToken authzToken, java.lang.String airavataInternalGatewayId, java.lang.String gatewayId) throws org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_deleteGateway(authzToken, airavataInternalGatewayId, gatewayId);
      return recv_deleteGateway();
    }

    public void send_deleteGateway(org.apache.airavata.model.security.AuthzToken authzToken, java.lang.String airavataInternalGatewayId, java.lang.String gatewayId) throws org.apache.thrift.TException
    {
      deleteGateway_args args = new deleteGateway_args();
      args.setAuthzToken(authzToken);
      args.setAiravataInternalGatewayId(airavataInternalGatewayId);
      args.setGatewayId(gatewayId);
      sendBase("deleteGateway", args);
    }

    public boolean recv_deleteGateway() throws org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      deleteGateway_result result = new deleteGateway_result();
      receiveBase(result, "deleteGateway");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.tpe != null) {
        throw result.tpe;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "deleteGateway failed: unknown result");
    }

    public java.util.List<org.apache.airavata.model.workspace.Gateway> getAllGateways(org.apache.airavata.model.security.AuthzToken authzToken) throws org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_getAllGateways(authzToken);
      return recv_getAllGateways();
    }

    public void send_getAllGateways(org.apache.airavata.model.security.AuthzToken authzToken) throws org.apache.thrift.TException
    {
      getAllGateways_args args = new getAllGateways_args();
      args.setAuthzToken(authzToken);
      sendBase("getAllGateways", args);
    }

    public java.util.List<org.apache.airavata.model.workspace.Gateway> recv_getAllGateways() throws org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      getAllGateways_result result = new getAllGateways_result();
      receiveBase(result, "getAllGateways");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.tpe != null) {
        throw result.tpe;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getAllGateways failed: unknown result");
    }

    public boolean isGatewayExist(org.apache.airavata.model.security.AuthzToken authzToken, java.lang.String gatewayId) throws org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_isGatewayExist(authzToken, gatewayId);
      return recv_isGatewayExist();
    }

    public void send_isGatewayExist(org.apache.airavata.model.security.AuthzToken authzToken, java.lang.String gatewayId) throws org.apache.thrift.TException
    {
      isGatewayExist_args args = new isGatewayExist_args();
      args.setAuthzToken(authzToken);
      args.setGatewayId(gatewayId);
      sendBase("isGatewayExist", args);
    }

    public boolean recv_isGatewayExist() throws org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      isGatewayExist_result result = new isGatewayExist_result();
      receiveBase(result, "isGatewayExist");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.tpe != null) {
        throw result.tpe;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "isGatewayExist failed: unknown result");
    }

    public java.util.List<org.apache.airavata.model.workspace.Gateway> getAllGatewaysForUser(org.apache.airavata.model.security.AuthzToken authzToken, java.lang.String requesterUsername) throws org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_getAllGatewaysForUser(authzToken, requesterUsername);
      return recv_getAllGatewaysForUser();
    }

    public void send_getAllGatewaysForUser(org.apache.airavata.model.security.AuthzToken authzToken, java.lang.String requesterUsername) throws org.apache.thrift.TException
    {
      getAllGatewaysForUser_args args = new getAllGatewaysForUser_args();
      args.setAuthzToken(authzToken);
      args.setRequesterUsername(requesterUsername);
      sendBase("getAllGatewaysForUser", args);
    }

    public java.util.List<org.apache.airavata.model.workspace.Gateway> recv_getAllGatewaysForUser() throws org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      getAllGatewaysForUser_result result = new getAllGatewaysForUser_result();
      receiveBase(result, "getAllGatewaysForUser");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.tpe != null) {
        throw result.tpe;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getAllGatewaysForUser failed: unknown result");
    }

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

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

    public void addGateway(org.apache.airavata.model.security.AuthzToken authzToken, org.apache.airavata.model.workspace.Gateway gateway, org.apache.thrift.async.AsyncMethodCallback<java.lang.String> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      addGateway_call method_call = new addGateway_call(authzToken, gateway, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class addGateway_call extends org.apache.thrift.async.TAsyncMethodCall<java.lang.String> {
      private org.apache.airavata.model.security.AuthzToken authzToken;
      private org.apache.airavata.model.workspace.Gateway gateway;
      public addGateway_call(org.apache.airavata.model.security.AuthzToken authzToken, org.apache.airavata.model.workspace.Gateway gateway, org.apache.thrift.async.AsyncMethodCallback<java.lang.String> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.authzToken = authzToken;
        this.gateway = gateway;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("addGateway", org.apache.thrift.protocol.TMessageType.CALL, 0));
        addGateway_args args = new addGateway_args();
        args.setAuthzToken(authzToken);
        args.setGateway(gateway);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public java.lang.String getResult() throws org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new java.lang.IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_addGateway();
      }
    }

    public void updateGateway(org.apache.airavata.model.security.AuthzToken authzToken, org.apache.airavata.model.workspace.Gateway updatedGateway, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      updateGateway_call method_call = new updateGateway_call(authzToken, updatedGateway, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class updateGateway_call extends org.apache.thrift.async.TAsyncMethodCall<java.lang.Boolean> {
      private org.apache.airavata.model.security.AuthzToken authzToken;
      private org.apache.airavata.model.workspace.Gateway updatedGateway;
      public updateGateway_call(org.apache.airavata.model.security.AuthzToken authzToken, org.apache.airavata.model.workspace.Gateway updatedGateway, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.authzToken = authzToken;
        this.updatedGateway = updatedGateway;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("updateGateway", org.apache.thrift.protocol.TMessageType.CALL, 0));
        updateGateway_args args = new updateGateway_args();
        args.setAuthzToken(authzToken);
        args.setUpdatedGateway(updatedGateway);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public java.lang.Boolean getResult() throws org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new java.lang.IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_updateGateway();
      }
    }

    public void getGateway(org.apache.airavata.model.security.AuthzToken authzToken, java.lang.String airavataInternalGatewayId, org.apache.thrift.async.AsyncMethodCallback<org.apache.airavata.model.workspace.Gateway> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      getGateway_call method_call = new getGateway_call(authzToken, airavataInternalGatewayId, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class getGateway_call extends org.apache.thrift.async.TAsyncMethodCall<org.apache.airavata.model.workspace.Gateway> {
      private org.apache.airavata.model.security.AuthzToken authzToken;
      private java.lang.String airavataInternalGatewayId;
      public getGateway_call(org.apache.airavata.model.security.AuthzToken authzToken, java.lang.String airavataInternalGatewayId, org.apache.thrift.async.AsyncMethodCallback<org.apache.airavata.model.workspace.Gateway> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.authzToken = authzToken;
        this.airavataInternalGatewayId = airavataInternalGatewayId;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("getGateway", org.apache.thrift.protocol.TMessageType.CALL, 0));
        getGateway_args args = new getGateway_args();
        args.setAuthzToken(authzToken);
        args.setAiravataInternalGatewayId(airavataInternalGatewayId);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public org.apache.airavata.model.workspace.Gateway getResult() throws org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new java.lang.IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_getGateway();
      }
    }

    public void deleteGateway(org.apache.airavata.model.security.AuthzToken authzToken, java.lang.String airavataInternalGatewayId, java.lang.String gatewayId, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      deleteGateway_call method_call = new deleteGateway_call(authzToken, airavataInternalGatewayId, gatewayId, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class deleteGateway_call extends org.apache.thrift.async.TAsyncMethodCall<java.lang.Boolean> {
      private org.apache.airavata.model.security.AuthzToken authzToken;
      private java.lang.String airavataInternalGatewayId;
      private java.lang.String gatewayId;
      public deleteGateway_call(org.apache.airavata.model.security.AuthzToken authzToken, java.lang.String airavataInternalGatewayId, java.lang.String gatewayId, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.authzToken = authzToken;
        this.airavataInternalGatewayId = airavataInternalGatewayId;
        this.gatewayId = gatewayId;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("deleteGateway", org.apache.thrift.protocol.TMessageType.CALL, 0));
        deleteGateway_args args = new deleteGateway_args();
        args.setAuthzToken(authzToken);
        args.setAiravataInternalGatewayId(airavataInternalGatewayId);
        args.setGatewayId(gatewayId);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public java.lang.Boolean getResult() throws org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new java.lang.IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_deleteGateway();
      }
    }

    public void getAllGateways(org.apache.airavata.model.security.AuthzToken authzToken, org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.model.workspace.Gateway>> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      getAllGateways_call method_call = new getAllGateways_call(authzToken, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class getAllGateways_call extends org.apache.thrift.async.TAsyncMethodCall<java.util.List<org.apache.airavata.model.workspace.Gateway>> {
      private org.apache.airavata.model.security.AuthzToken authzToken;
      public getAllGateways_call(org.apache.airavata.model.security.AuthzToken authzToken, org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.model.workspace.Gateway>> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.authzToken = authzToken;
      }

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

      public java.util.List<org.apache.airavata.model.workspace.Gateway> getResult() throws org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new java.lang.IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_getAllGateways();
      }
    }

    public void isGatewayExist(org.apache.airavata.model.security.AuthzToken authzToken, java.lang.String gatewayId, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      isGatewayExist_call method_call = new isGatewayExist_call(authzToken, gatewayId, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class isGatewayExist_call extends org.apache.thrift.async.TAsyncMethodCall<java.lang.Boolean> {
      private org.apache.airavata.model.security.AuthzToken authzToken;
      private java.lang.String gatewayId;
      public isGatewayExist_call(org.apache.airavata.model.security.AuthzToken authzToken, java.lang.String gatewayId, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.authzToken = authzToken;
        this.gatewayId = gatewayId;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("isGatewayExist", org.apache.thrift.protocol.TMessageType.CALL, 0));
        isGatewayExist_args args = new isGatewayExist_args();
        args.setAuthzToken(authzToken);
        args.setGatewayId(gatewayId);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public java.lang.Boolean getResult() throws org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new java.lang.IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_isGatewayExist();
      }
    }

    public void getAllGatewaysForUser(org.apache.airavata.model.security.AuthzToken authzToken, java.lang.String requesterUsername, org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.model.workspace.Gateway>> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      getAllGatewaysForUser_call method_call = new getAllGatewaysForUser_call(authzToken, requesterUsername, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class getAllGatewaysForUser_call extends org.apache.thrift.async.TAsyncMethodCall<java.util.List<org.apache.airavata.model.workspace.Gateway>> {
      private org.apache.airavata.model.security.AuthzToken authzToken;
      private java.lang.String requesterUsername;
      public getAllGatewaysForUser_call(org.apache.airavata.model.security.AuthzToken authzToken, java.lang.String requesterUsername, org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.model.workspace.Gateway>> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.authzToken = authzToken;
        this.requesterUsername = requesterUsername;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("getAllGatewaysForUser", org.apache.thrift.protocol.TMessageType.CALL, 0));
        getAllGatewaysForUser_args args = new getAllGatewaysForUser_args();
        args.setAuthzToken(authzToken);
        args.setRequesterUsername(requesterUsername);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public java.util.List<org.apache.airavata.model.workspace.Gateway> getResult() throws org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new java.lang.IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_getAllGatewaysForUser();
      }
    }

  }

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

    protected Processor(I iface, java.util.Map<java.lang.String, org.apache.thrift.ProcessFunction<I, ? extends org.apache.thrift.TBase>> processMap) {
      super(iface, getProcessMap(processMap));
    }

    private static <I extends Iface> java.util.Map<java.lang.String,  org.apache.thrift.ProcessFunction<I, ? extends org.apache.thrift.TBase>> getProcessMap(java.util.Map<java.lang.String, org.apache.thrift.ProcessFunction<I, ? extends  org.apache.thrift.TBase>> processMap) {
      processMap.put("addGateway", new addGateway());
      processMap.put("updateGateway", new updateGateway());
      processMap.put("getGateway", new getGateway());
      processMap.put("deleteGateway", new deleteGateway());
      processMap.put("getAllGateways", new getAllGateways());
      processMap.put("isGatewayExist", new isGatewayExist());
      processMap.put("getAllGatewaysForUser", new getAllGatewaysForUser());
      return processMap;
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public addGateway_result getResult(I iface, addGateway_args args) throws org.apache.thrift.TException {
        addGateway_result result = new addGateway_result();
        try {
          result.success = iface.addGateway(args.authzToken, args.gateway);
        } catch (org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException tpe) {
          result.tpe = tpe;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public updateGateway_result getResult(I iface, updateGateway_args args) throws org.apache.thrift.TException {
        updateGateway_result result = new updateGateway_result();
        try {
          result.success = iface.updateGateway(args.authzToken, args.updatedGateway);
          result.setSuccessIsSet(true);
        } catch (org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException tpe) {
          result.tpe = tpe;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public getGateway_result getResult(I iface, getGateway_args args) throws org.apache.thrift.TException {
        getGateway_result result = new getGateway_result();
        try {
          result.success = iface.getGateway(args.authzToken, args.airavataInternalGatewayId);
        } catch (org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException tpe) {
          result.tpe = tpe;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public deleteGateway_result getResult(I iface, deleteGateway_args args) throws org.apache.thrift.TException {
        deleteGateway_result result = new deleteGateway_result();
        try {
          result.success = iface.deleteGateway(args.authzToken, args.airavataInternalGatewayId, args.gatewayId);
          result.setSuccessIsSet(true);
        } catch (org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException tpe) {
          result.tpe = tpe;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public getAllGateways_result getResult(I iface, getAllGateways_args args) throws org.apache.thrift.TException {
        getAllGateways_result result = new getAllGateways_result();
        try {
          result.success = iface.getAllGateways(args.authzToken);
        } catch (org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException tpe) {
          result.tpe = tpe;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public isGatewayExist_result getResult(I iface, isGatewayExist_args args) throws org.apache.thrift.TException {
        isGatewayExist_result result = new isGatewayExist_result();
        try {
          result.success = iface.isGatewayExist(args.authzToken, args.gatewayId);
          result.setSuccessIsSet(true);
        } catch (org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException tpe) {
          result.tpe = tpe;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public getAllGatewaysForUser_result getResult(I iface, getAllGatewaysForUser_args args) throws org.apache.thrift.TException {
        getAllGatewaysForUser_result result = new getAllGatewaysForUser_result();
        try {
          result.success = iface.getAllGatewaysForUser(args.authzToken, args.requesterUsername);
        } catch (org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException tpe) {
          result.tpe = tpe;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

  }

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

    protected AsyncProcessor(I iface, java.util.Map<java.lang.String,  org.apache.thrift.AsyncProcessFunction<I, ? extends  org.apache.thrift.TBase, ?>> processMap) {
      super(iface, getProcessMap(processMap));
    }

    private static <I extends AsyncIface> java.util.Map<java.lang.String,  org.apache.thrift.AsyncProcessFunction<I, ? extends  org.apache.thrift.TBase,?>> getProcessMap(java.util.Map<java.lang.String,  org.apache.thrift.AsyncProcessFunction<I, ? extends  org.apache.thrift.TBase, ?>> processMap) {
      processMap.put("addGateway", new addGateway());
      processMap.put("updateGateway", new updateGateway());
      processMap.put("getGateway", new getGateway());
      processMap.put("deleteGateway", new deleteGateway());
      processMap.put("getAllGateways", new getAllGateways());
      processMap.put("isGatewayExist", new isGatewayExist());
      processMap.put("getAllGatewaysForUser", new getAllGatewaysForUser());
      return processMap;
    }

    public static class addGateway<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, addGateway_args, java.lang.String> {
      public addGateway() {
        super("addGateway");
      }

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

      public org.apache.thrift.async.AsyncMethodCallback<java.lang.String> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new org.apache.thrift.async.AsyncMethodCallback<java.lang.String>() { 
          public void onComplete(java.lang.String o) {
            addGateway_result result = new addGateway_result();
            result.success = o;
            try {
              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
            } catch (org.apache.thrift.transport.TTransportException e) {
              _LOGGER.error("TTransportException writing to internal frame buffer", e);
              fb.close();
            } catch (java.lang.Exception e) {
              _LOGGER.error("Exception writing to internal frame buffer", e);
              onError(e);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TSerializable msg;
            addGateway_result result = new addGateway_result();
            if (e instanceof org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException) {
              result.tpe = (org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException) e;
              result.setTpeIsSet(true);
              msg = result;
            } else if (e instanceof org.apache.airavata.model.error.AuthorizationException) {
              result.ae = (org.apache.airavata.model.error.AuthorizationException) e;
              result.setAeIsSet(true);
              msg = result;
            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
              _LOGGER.error("TTransportException inside handler", e);
              fb.close();
              return;
            } else if (e instanceof org.apache.thrift.TApplicationException) {
              _LOGGER.error("TApplicationException inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TApplicationException)e;
            } else {
              _LOGGER.error("Exception inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, addGateway_args args, org.apache.thrift.async.AsyncMethodCallback<java.lang.String> resultHandler) throws org.apache.thrift.TException {
        iface.addGateway(args.authzToken, args.gateway,resultHandler);
      }
    }

    public static class updateGateway<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, updateGateway_args, java.lang.Boolean> {
      public updateGateway() {
        super("updateGateway");
      }

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

      public org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean>() { 
          public void onComplete(java.lang.Boolean o) {
            updateGateway_result result = new updateGateway_result();
            result.success = o;
            result.setSuccessIsSet(true);
            try {
              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
            } catch (org.apache.thrift.transport.TTransportException e) {
              _LOGGER.error("TTransportException writing to internal frame buffer", e);
              fb.close();
            } catch (java.lang.Exception e) {
              _LOGGER.error("Exception writing to internal frame buffer", e);
              onError(e);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TSerializable msg;
            updateGateway_result result = new updateGateway_result();
            if (e instanceof org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException) {
              result.tpe = (org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException) e;
              result.setTpeIsSet(true);
              msg = result;
            } else if (e instanceof org.apache.airavata.model.error.AuthorizationException) {
              result.ae = (org.apache.airavata.model.error.AuthorizationException) e;
              result.setAeIsSet(true);
              msg = result;
            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
              _LOGGER.error("TTransportException inside handler", e);
              fb.close();
              return;
            } else if (e instanceof org.apache.thrift.TApplicationException) {
              _LOGGER.error("TApplicationException inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TApplicationException)e;
            } else {
              _LOGGER.error("Exception inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, updateGateway_args args, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
        iface.updateGateway(args.authzToken, args.updatedGateway,resultHandler);
      }
    }

    public static class getGateway<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getGateway_args, org.apache.airavata.model.workspace.Gateway> {
      public getGateway() {
        super("getGateway");
      }

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

      public org.apache.thrift.async.AsyncMethodCallback<org.apache.airavata.model.workspace.Gateway> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new org.apache.thrift.async.AsyncMethodCallback<org.apache.airavata.model.workspace.Gateway>() { 
          public void onComplete(org.apache.airavata.model.workspace.Gateway o) {
            getGateway_result result = new getGateway_result();
            result.success = o;
            try {
              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
            } catch (org.apache.thrift.transport.TTransportException e) {
              _LOGGER.error("TTransportException writing to internal frame buffer", e);
              fb.close();
            } catch (java.lang.Exception e) {
              _LOGGER.error("Exception writing to internal frame buffer", e);
              onError(e);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TSerializable msg;
            getGateway_result result = new getGateway_result();
            if (e instanceof org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException) {
              result.tpe = (org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException) e;
              result.setTpeIsSet(true);
              msg = result;
            } else if (e instanceof org.apache.airavata.model.error.AuthorizationException) {
              result.ae = (org.apache.airavata.model.error.AuthorizationException) e;
              result.setAeIsSet(true);
              msg = result;
            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
              _LOGGER.error("TTransportException inside handler", e);
              fb.close();
              return;
            } else if (e instanceof org.apache.thrift.TApplicationException) {
              _LOGGER.error("TApplicationException inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TApplicationException)e;
            } else {
              _LOGGER.error("Exception inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, getGateway_args args, org.apache.thrift.async.AsyncMethodCallback<org.apache.airavata.model.workspace.Gateway> resultHandler) throws org.apache.thrift.TException {
        iface.getGateway(args.authzToken, args.airavataInternalGatewayId,resultHandler);
      }
    }

    public static class deleteGateway<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, deleteGateway_args, java.lang.Boolean> {
      public deleteGateway() {
        super("deleteGateway");
      }

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

      public org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean>() { 
          public void onComplete(java.lang.Boolean o) {
            deleteGateway_result result = new deleteGateway_result();
            result.success = o;
            result.setSuccessIsSet(true);
            try {
              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
            } catch (org.apache.thrift.transport.TTransportException e) {
              _LOGGER.error("TTransportException writing to internal frame buffer", e);
              fb.close();
            } catch (java.lang.Exception e) {
              _LOGGER.error("Exception writing to internal frame buffer", e);
              onError(e);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TSerializable msg;
            deleteGateway_result result = new deleteGateway_result();
            if (e instanceof org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException) {
              result.tpe = (org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException) e;
              result.setTpeIsSet(true);
              msg = result;
            } else if (e instanceof org.apache.airavata.model.error.AuthorizationException) {
              result.ae = (org.apache.airavata.model.error.AuthorizationException) e;
              result.setAeIsSet(true);
              msg = result;
            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
              _LOGGER.error("TTransportException inside handler", e);
              fb.close();
              return;
            } else if (e instanceof org.apache.thrift.TApplicationException) {
              _LOGGER.error("TApplicationException inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TApplicationException)e;
            } else {
              _LOGGER.error("Exception inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, deleteGateway_args args, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
        iface.deleteGateway(args.authzToken, args.airavataInternalGatewayId, args.gatewayId,resultHandler);
      }
    }

    public static class getAllGateways<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getAllGateways_args, java.util.List<org.apache.airavata.model.workspace.Gateway>> {
      public getAllGateways() {
        super("getAllGateways");
      }

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

      public org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.model.workspace.Gateway>> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.model.workspace.Gateway>>() { 
          public void onComplete(java.util.List<org.apache.airavata.model.workspace.Gateway> o) {
            getAllGateways_result result = new getAllGateways_result();
            result.success = o;
            try {
              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
            } catch (org.apache.thrift.transport.TTransportException e) {
              _LOGGER.error("TTransportException writing to internal frame buffer", e);
              fb.close();
            } catch (java.lang.Exception e) {
              _LOGGER.error("Exception writing to internal frame buffer", e);
              onError(e);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TSerializable msg;
            getAllGateways_result result = new getAllGateways_result();
            if (e instanceof org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException) {
              result.tpe = (org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException) e;
              result.setTpeIsSet(true);
              msg = result;
            } else if (e instanceof org.apache.airavata.model.error.AuthorizationException) {
              result.ae = (org.apache.airavata.model.error.AuthorizationException) e;
              result.setAeIsSet(true);
              msg = result;
            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
              _LOGGER.error("TTransportException inside handler", e);
              fb.close();
              return;
            } else if (e instanceof org.apache.thrift.TApplicationException) {
              _LOGGER.error("TApplicationException inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TApplicationException)e;
            } else {
              _LOGGER.error("Exception inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, getAllGateways_args args, org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.model.workspace.Gateway>> resultHandler) throws org.apache.thrift.TException {
        iface.getAllGateways(args.authzToken,resultHandler);
      }
    }

    public static class isGatewayExist<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, isGatewayExist_args, java.lang.Boolean> {
      public isGatewayExist() {
        super("isGatewayExist");
      }

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

      public org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean>() { 
          public void onComplete(java.lang.Boolean o) {
            isGatewayExist_result result = new isGatewayExist_result();
            result.success = o;
            result.setSuccessIsSet(true);
            try {
              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
            } catch (org.apache.thrift.transport.TTransportException e) {
              _LOGGER.error("TTransportException writing to internal frame buffer", e);
              fb.close();
            } catch (java.lang.Exception e) {
              _LOGGER.error("Exception writing to internal frame buffer", e);
              onError(e);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TSerializable msg;
            isGatewayExist_result result = new isGatewayExist_result();
            if (e instanceof org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException) {
              result.tpe = (org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException) e;
              result.setTpeIsSet(true);
              msg = result;
            } else if (e instanceof org.apache.airavata.model.error.AuthorizationException) {
              result.ae = (org.apache.airavata.model.error.AuthorizationException) e;
              result.setAeIsSet(true);
              msg = result;
            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
              _LOGGER.error("TTransportException inside handler", e);
              fb.close();
              return;
            } else if (e instanceof org.apache.thrift.TApplicationException) {
              _LOGGER.error("TApplicationException inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TApplicationException)e;
            } else {
              _LOGGER.error("Exception inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, isGatewayExist_args args, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
        iface.isGatewayExist(args.authzToken, args.gatewayId,resultHandler);
      }
    }

    public static class getAllGatewaysForUser<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getAllGatewaysForUser_args, java.util.List<org.apache.airavata.model.workspace.Gateway>> {
      public getAllGatewaysForUser() {
        super("getAllGatewaysForUser");
      }

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

      public org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.model.workspace.Gateway>> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.model.workspace.Gateway>>() { 
          public void onComplete(java.util.List<org.apache.airavata.model.workspace.Gateway> o) {
            getAllGatewaysForUser_result result = new getAllGatewaysForUser_result();
            result.success = o;
            try {
              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
            } catch (org.apache.thrift.transport.TTransportException e) {
              _LOGGER.error("TTransportException writing to internal frame buffer", e);
              fb.close();
            } catch (java.lang.Exception e) {
              _LOGGER.error("Exception writing to internal frame buffer", e);
              onError(e);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TSerializable msg;
            getAllGatewaysForUser_result result = new getAllGatewaysForUser_result();
            if (e instanceof org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException) {
              result.tpe = (org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException) e;
              result.setTpeIsSet(true);
              msg = result;
            } else if (e instanceof org.apache.airavata.model.error.AuthorizationException) {
              result.ae = (org.apache.airavata.model.error.AuthorizationException) e;
              result.setAeIsSet(true);
              msg = result;
            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
              _LOGGER.error("TTransportException inside handler", e);
              fb.close();
              return;
            } else if (e instanceof org.apache.thrift.TApplicationException) {
              _LOGGER.error("TApplicationException inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TApplicationException)e;
            } else {
              _LOGGER.error("Exception inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, getAllGatewaysForUser_args args, org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.model.workspace.Gateway>> resultHandler) throws org.apache.thrift.TException {
        iface.getAllGatewaysForUser(args.authzToken, args.requesterUsername,resultHandler);
      }
    }

  }

  public static class addGateway_args implements org.apache.thrift.TBase<addGateway_args, addGateway_args._Fields>, java.io.Serializable, Cloneable, Comparable<addGateway_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("addGateway_args");

    private static final org.apache.thrift.protocol.TField AUTHZ_TOKEN_FIELD_DESC = new org.apache.thrift.protocol.TField("authzToken", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField GATEWAY_FIELD_DESC = new org.apache.thrift.protocol.TField("gateway", org.apache.thrift.protocol.TType.STRUCT, (short)2);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new addGateway_argsStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new addGateway_argsTupleSchemeFactory();

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public org.apache.airavata.model.workspace.Gateway gateway; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      AUTHZ_TOKEN((short)1, "authzToken"),
      GATEWAY((short)2, "gateway");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // GATEWAY
            return GATEWAY;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.AUTHZ_TOKEN, new org.apache.thrift.meta_data.FieldMetaData("authzToken", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.security.AuthzToken.class)));
      tmpMap.put(_Fields.GATEWAY, new org.apache.thrift.meta_data.FieldMetaData("gateway", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.workspace.Gateway.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(addGateway_args.class, metaDataMap);
    }

    public addGateway_args() {
    }

    public addGateway_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      org.apache.airavata.model.workspace.Gateway gateway)
    {
      this();
      this.authzToken = authzToken;
      this.gateway = gateway;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public addGateway_args(addGateway_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetGateway()) {
        this.gateway = new org.apache.airavata.model.workspace.Gateway(other.gateway);
      }
    }

    public addGateway_args deepCopy() {
      return new addGateway_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.gateway = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public addGateway_args setAuthzToken(org.apache.airavata.model.security.AuthzToken authzToken) {
      this.authzToken = authzToken;
      return this;
    }

    public void unsetAuthzToken() {
      this.authzToken = null;
    }

    /** Returns true if field authzToken is set (has been assigned a value) and false otherwise */
    public boolean isSetAuthzToken() {
      return this.authzToken != null;
    }

    public void setAuthzTokenIsSet(boolean value) {
      if (!value) {
        this.authzToken = null;
      }
    }

    public org.apache.airavata.model.workspace.Gateway getGateway() {
      return this.gateway;
    }

    public addGateway_args setGateway(org.apache.airavata.model.workspace.Gateway gateway) {
      this.gateway = gateway;
      return this;
    }

    public void unsetGateway() {
      this.gateway = null;
    }

    /** Returns true if field gateway is set (has been assigned a value) and false otherwise */
    public boolean isSetGateway() {
      return this.gateway != null;
    }

    public void setGatewayIsSet(boolean value) {
      if (!value) {
        this.gateway = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case AUTHZ_TOKEN:
        if (value == null) {
          unsetAuthzToken();
        } else {
          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
        }
        break;

      case GATEWAY:
        if (value == null) {
          unsetGateway();
        } else {
          setGateway((org.apache.airavata.model.workspace.Gateway)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case GATEWAY:
        return getGateway();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case GATEWAY:
        return isSetGateway();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof addGateway_args)
        return this.equals((addGateway_args)that);
      return false;
    }

    public boolean equals(addGateway_args that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_authzToken = true && this.isSetAuthzToken();
      boolean that_present_authzToken = true && that.isSetAuthzToken();
      if (this_present_authzToken || that_present_authzToken) {
        if (!(this_present_authzToken && that_present_authzToken))
          return false;
        if (!this.authzToken.equals(that.authzToken))
          return false;
      }

      boolean this_present_gateway = true && this.isSetGateway();
      boolean that_present_gateway = true && that.isSetGateway();
      if (this_present_gateway || that_present_gateway) {
        if (!(this_present_gateway && that_present_gateway))
          return false;
        if (!this.gateway.equals(that.gateway))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetAuthzToken()) ? 131071 : 524287);
      if (isSetAuthzToken())
        hashCode = hashCode * 8191 + authzToken.hashCode();

      hashCode = hashCode * 8191 + ((isSetGateway()) ? 131071 : 524287);
      if (isSetGateway())
        hashCode = hashCode * 8191 + gateway.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(addGateway_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetAuthzToken()).compareTo(other.isSetAuthzToken());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAuthzToken()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.authzToken, other.authzToken);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetGateway()).compareTo(other.isSetGateway());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetGateway()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.gateway, other.gateway);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("addGateway_args(");
      boolean first = true;

      sb.append("authzToken:");
      if (this.authzToken == null) {
        sb.append("null");
      } else {
        sb.append(this.authzToken);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("gateway:");
      if (this.gateway == null) {
        sb.append("null");
      } else {
        sb.append(this.gateway);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (authzToken == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'authzToken' was not present! Struct: " + toString());
      }
      if (gateway == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'gateway' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
      if (authzToken != null) {
        authzToken.validate();
      }
      if (gateway != null) {
        gateway.validate();
      }
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class addGateway_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public addGateway_argsStandardScheme getScheme() {
        return new addGateway_argsStandardScheme();
      }
    }

    private static class addGateway_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<addGateway_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, addGateway_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TField schemeField;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // AUTHZ_TOKEN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
                struct.authzToken.read(iprot);
                struct.setAuthzTokenIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // GATEWAY
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.gateway = new org.apache.airavata.model.workspace.Gateway();
                struct.gateway.read(iprot);
                struct.setGatewayIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, addGateway_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.authzToken != null) {
          oprot.writeFieldBegin(AUTHZ_TOKEN_FIELD_DESC);
          struct.authzToken.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.gateway != null) {
          oprot.writeFieldBegin(GATEWAY_FIELD_DESC);
          struct.gateway.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class addGateway_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public addGateway_argsTupleScheme getScheme() {
        return new addGateway_argsTupleScheme();
      }
    }

    private static class addGateway_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<addGateway_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, addGateway_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        struct.gateway.write(oprot);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, addGateway_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
        struct.authzToken.read(iprot);
        struct.setAuthzTokenIsSet(true);
        struct.gateway = new org.apache.airavata.model.workspace.Gateway();
        struct.gateway.read(iprot);
        struct.setGatewayIsSet(true);
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class addGateway_result implements org.apache.thrift.TBase<addGateway_result, addGateway_result._Fields>, java.io.Serializable, Cloneable, Comparable<addGateway_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("addGateway_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.STRING, (short)0);
    private static final org.apache.thrift.protocol.TField TPE_FIELD_DESC = new org.apache.thrift.protocol.TField("tpe", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField AE_FIELD_DESC = new org.apache.thrift.protocol.TField("ae", org.apache.thrift.protocol.TType.STRUCT, (short)2);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new addGateway_resultStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new addGateway_resultTupleSchemeFactory();

    public java.lang.String success; // required
    public org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException tpe; // required
    public org.apache.airavata.model.error.AuthorizationException ae; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      TPE((short)1, "tpe"),
      AE((short)2, "ae");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // TPE
            return TPE;
          case 2: // AE
            return AE;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.TPE, new org.apache.thrift.meta_data.FieldMetaData("tpe", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException.class)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.error.AuthorizationException.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(addGateway_result.class, metaDataMap);
    }

    public addGateway_result() {
    }

    public addGateway_result(
      java.lang.String success,
      org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException tpe,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      this.tpe = tpe;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public addGateway_result(addGateway_result other) {
      if (other.isSetSuccess()) {
        this.success = other.success;
      }
      if (other.isSetTpe()) {
        this.tpe = new org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException(other.tpe);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public addGateway_result deepCopy() {
      return new addGateway_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.tpe = null;
      this.ae = null;
    }

    public java.lang.String getSuccess() {
      return this.success;
    }

    public addGateway_result setSuccess(java.lang.String success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return this.success != null;
    }

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException getTpe() {
      return this.tpe;
    }

    public addGateway_result setTpe(org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException tpe) {
      this.tpe = tpe;
      return this;
    }

    public void unsetTpe() {
      this.tpe = null;
    }

    /** Returns true if field tpe is set (has been assigned a value) and false otherwise */
    public boolean isSetTpe() {
      return this.tpe != null;
    }

    public void setTpeIsSet(boolean value) {
      if (!value) {
        this.tpe = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public addGateway_result setAe(org.apache.airavata.model.error.AuthorizationException ae) {
      this.ae = ae;
      return this;
    }

    public void unsetAe() {
      this.ae = null;
    }

    /** Returns true if field ae is set (has been assigned a value) and false otherwise */
    public boolean isSetAe() {
      return this.ae != null;
    }

    public void setAeIsSet(boolean value) {
      if (!value) {
        this.ae = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.lang.String)value);
        }
        break;

      case TPE:
        if (value == null) {
          unsetTpe();
        } else {
          setTpe((org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case TPE:
        return getTpe();

      case AE:
        return getAe();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case TPE:
        return isSetTpe();
      case AE:
        return isSetAe();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof addGateway_result)
        return this.equals((addGateway_result)that);
      return false;
    }

    public boolean equals(addGateway_result that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_tpe = true && this.isSetTpe();
      boolean that_present_tpe = true && that.isSetTpe();
      if (this_present_tpe || that_present_tpe) {
        if (!(this_present_tpe && that_present_tpe))
          return false;
        if (!this.tpe.equals(that.tpe))
          return false;
      }

      boolean this_present_ae = true && this.isSetAe();
      boolean that_present_ae = true && that.isSetAe();
      if (this_present_ae || that_present_ae) {
        if (!(this_present_ae && that_present_ae))
          return false;
        if (!this.ae.equals(that.ae))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
      if (isSetSuccess())
        hashCode = hashCode * 8191 + success.hashCode();

      hashCode = hashCode * 8191 + ((isSetTpe()) ? 131071 : 524287);
      if (isSetTpe())
        hashCode = hashCode * 8191 + tpe.hashCode();

      hashCode = hashCode * 8191 + ((isSetAe()) ? 131071 : 524287);
      if (isSetAe())
        hashCode = hashCode * 8191 + ae.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(addGateway_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetTpe()).compareTo(other.isSetTpe());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetTpe()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.tpe, other.tpe);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetAe()).compareTo(other.isSetAe());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAe()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ae, other.ae);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("addGateway_result(");
      boolean first = true;

      sb.append("success:");
      if (this.success == null) {
        sb.append("null");
      } else {
        sb.append(this.success);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("tpe:");
      if (this.tpe == null) {
        sb.append("null");
      } else {
        sb.append(this.tpe);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ae:");
      if (this.ae == null) {
        sb.append("null");
      } else {
        sb.append(this.ae);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class addGateway_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public addGateway_resultStandardScheme getScheme() {
        return new addGateway_resultStandardScheme();
      }
    }

    private static class addGateway_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<addGateway_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, addGateway_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TField schemeField;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.success = iprot.readString();
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // TPE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.tpe = new org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException();
                struct.tpe.read(iprot);
                struct.setTpeIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // AE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ae = new org.apache.airavata.model.error.AuthorizationException();
                struct.ae.read(iprot);
                struct.setAeIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, addGateway_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          oprot.writeString(struct.success);
          oprot.writeFieldEnd();
        }
        if (struct.tpe != null) {
          oprot.writeFieldBegin(TPE_FIELD_DESC);
          struct.tpe.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ae != null) {
          oprot.writeFieldBegin(AE_FIELD_DESC);
          struct.ae.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class addGateway_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public addGateway_resultTupleScheme getScheme() {
        return new addGateway_resultTupleScheme();
      }
    }

    private static class addGateway_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<addGateway_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, addGateway_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet optionals = new java.util.BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetTpe()) {
          optionals.set(1);
        }
        if (struct.isSetAe()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetSuccess()) {
          oprot.writeString(struct.success);
        }
        if (struct.isSetTpe()) {
          struct.tpe.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, addGateway_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet incoming = iprot.readBitSet(3);
        if (incoming.get(0)) {
          struct.success = iprot.readString();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.tpe = new org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException();
          struct.tpe.read(iprot);
          struct.setTpeIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class updateGateway_args implements org.apache.thrift.TBase<updateGateway_args, updateGateway_args._Fields>, java.io.Serializable, Cloneable, Comparable<updateGateway_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("updateGateway_args");

    private static final org.apache.thrift.protocol.TField AUTHZ_TOKEN_FIELD_DESC = new org.apache.thrift.protocol.TField("authzToken", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField UPDATED_GATEWAY_FIELD_DESC = new org.apache.thrift.protocol.TField("updatedGateway", org.apache.thrift.protocol.TType.STRUCT, (short)2);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new updateGateway_argsStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new updateGateway_argsTupleSchemeFactory();

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public org.apache.airavata.model.workspace.Gateway updatedGateway; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      AUTHZ_TOKEN((short)1, "authzToken"),
      UPDATED_GATEWAY((short)2, "updatedGateway");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // UPDATED_GATEWAY
            return UPDATED_GATEWAY;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.AUTHZ_TOKEN, new org.apache.thrift.meta_data.FieldMetaData("authzToken", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.security.AuthzToken.class)));
      tmpMap.put(_Fields.UPDATED_GATEWAY, new org.apache.thrift.meta_data.FieldMetaData("updatedGateway", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.workspace.Gateway.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(updateGateway_args.class, metaDataMap);
    }

    public updateGateway_args() {
    }

    public updateGateway_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      org.apache.airavata.model.workspace.Gateway updatedGateway)
    {
      this();
      this.authzToken = authzToken;
      this.updatedGateway = updatedGateway;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public updateGateway_args(updateGateway_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetUpdatedGateway()) {
        this.updatedGateway = new org.apache.airavata.model.workspace.Gateway(other.updatedGateway);
      }
    }

    public updateGateway_args deepCopy() {
      return new updateGateway_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.updatedGateway = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public updateGateway_args setAuthzToken(org.apache.airavata.model.security.AuthzToken authzToken) {
      this.authzToken = authzToken;
      return this;
    }

    public void unsetAuthzToken() {
      this.authzToken = null;
    }

    /** Returns true if field authzToken is set (has been assigned a value) and false otherwise */
    public boolean isSetAuthzToken() {
      return this.authzToken != null;
    }

    public void setAuthzTokenIsSet(boolean value) {
      if (!value) {
        this.authzToken = null;
      }
    }

    public org.apache.airavata.model.workspace.Gateway getUpdatedGateway() {
      return this.updatedGateway;
    }

    public updateGateway_args setUpdatedGateway(org.apache.airavata.model.workspace.Gateway updatedGateway) {
      this.updatedGateway = updatedGateway;
      return this;
    }

    public void unsetUpdatedGateway() {
      this.updatedGateway = null;
    }

    /** Returns true if field updatedGateway is set (has been assigned a value) and false otherwise */
    public boolean isSetUpdatedGateway() {
      return this.updatedGateway != null;
    }

    public void setUpdatedGatewayIsSet(boolean value) {
      if (!value) {
        this.updatedGateway = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case AUTHZ_TOKEN:
        if (value == null) {
          unsetAuthzToken();
        } else {
          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
        }
        break;

      case UPDATED_GATEWAY:
        if (value == null) {
          unsetUpdatedGateway();
        } else {
          setUpdatedGateway((org.apache.airavata.model.workspace.Gateway)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case UPDATED_GATEWAY:
        return getUpdatedGateway();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case UPDATED_GATEWAY:
        return isSetUpdatedGateway();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof updateGateway_args)
        return this.equals((updateGateway_args)that);
      return false;
    }

    public boolean equals(updateGateway_args that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_authzToken = true && this.isSetAuthzToken();
      boolean that_present_authzToken = true && that.isSetAuthzToken();
      if (this_present_authzToken || that_present_authzToken) {
        if (!(this_present_authzToken && that_present_authzToken))
          return false;
        if (!this.authzToken.equals(that.authzToken))
          return false;
      }

      boolean this_present_updatedGateway = true && this.isSetUpdatedGateway();
      boolean that_present_updatedGateway = true && that.isSetUpdatedGateway();
      if (this_present_updatedGateway || that_present_updatedGateway) {
        if (!(this_present_updatedGateway && that_present_updatedGateway))
          return false;
        if (!this.updatedGateway.equals(that.updatedGateway))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetAuthzToken()) ? 131071 : 524287);
      if (isSetAuthzToken())
        hashCode = hashCode * 8191 + authzToken.hashCode();

      hashCode = hashCode * 8191 + ((isSetUpdatedGateway()) ? 131071 : 524287);
      if (isSetUpdatedGateway())
        hashCode = hashCode * 8191 + updatedGateway.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(updateGateway_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetAuthzToken()).compareTo(other.isSetAuthzToken());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAuthzToken()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.authzToken, other.authzToken);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetUpdatedGateway()).compareTo(other.isSetUpdatedGateway());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetUpdatedGateway()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.updatedGateway, other.updatedGateway);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("updateGateway_args(");
      boolean first = true;

      sb.append("authzToken:");
      if (this.authzToken == null) {
        sb.append("null");
      } else {
        sb.append(this.authzToken);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("updatedGateway:");
      if (this.updatedGateway == null) {
        sb.append("null");
      } else {
        sb.append(this.updatedGateway);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (authzToken == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'authzToken' was not present! Struct: " + toString());
      }
      if (updatedGateway == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'updatedGateway' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
      if (authzToken != null) {
        authzToken.validate();
      }
      if (updatedGateway != null) {
        updatedGateway.validate();
      }
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class updateGateway_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public updateGateway_argsStandardScheme getScheme() {
        return new updateGateway_argsStandardScheme();
      }
    }

    private static class updateGateway_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<updateGateway_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, updateGateway_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TField schemeField;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // AUTHZ_TOKEN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
                struct.authzToken.read(iprot);
                struct.setAuthzTokenIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // UPDATED_GATEWAY
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.updatedGateway = new org.apache.airavata.model.workspace.Gateway();
                struct.updatedGateway.read(iprot);
                struct.setUpdatedGatewayIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, updateGateway_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.authzToken != null) {
          oprot.writeFieldBegin(AUTHZ_TOKEN_FIELD_DESC);
          struct.authzToken.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.updatedGateway != null) {
          oprot.writeFieldBegin(UPDATED_GATEWAY_FIELD_DESC);
          struct.updatedGateway.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class updateGateway_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public updateGateway_argsTupleScheme getScheme() {
        return new updateGateway_argsTupleScheme();
      }
    }

    private static class updateGateway_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<updateGateway_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, updateGateway_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        struct.updatedGateway.write(oprot);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, updateGateway_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
        struct.authzToken.read(iprot);
        struct.setAuthzTokenIsSet(true);
        struct.updatedGateway = new org.apache.airavata.model.workspace.Gateway();
        struct.updatedGateway.read(iprot);
        struct.setUpdatedGatewayIsSet(true);
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class updateGateway_result implements org.apache.thrift.TBase<updateGateway_result, updateGateway_result._Fields>, java.io.Serializable, Cloneable, Comparable<updateGateway_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("updateGateway_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.BOOL, (short)0);
    private static final org.apache.thrift.protocol.TField TPE_FIELD_DESC = new org.apache.thrift.protocol.TField("tpe", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField AE_FIELD_DESC = new org.apache.thrift.protocol.TField("ae", org.apache.thrift.protocol.TType.STRUCT, (short)2);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new updateGateway_resultStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new updateGateway_resultTupleSchemeFactory();

    public boolean success; // required
    public org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException tpe; // required
    public org.apache.airavata.model.error.AuthorizationException ae; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      TPE((short)1, "tpe"),
      AE((short)2, "ae");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // TPE
            return TPE;
          case 2: // AE
            return AE;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __SUCCESS_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
      tmpMap.put(_Fields.TPE, new org.apache.thrift.meta_data.FieldMetaData("tpe", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException.class)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.error.AuthorizationException.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(updateGateway_result.class, metaDataMap);
    }

    public updateGateway_result() {
    }

    public updateGateway_result(
      boolean success,
      org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException tpe,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
      this.tpe = tpe;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public updateGateway_result(updateGateway_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
      if (other.isSetTpe()) {
        this.tpe = new org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException(other.tpe);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public updateGateway_result deepCopy() {
      return new updateGateway_result(this);
    }

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
      this.tpe = null;
      this.ae = null;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public updateGateway_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

    public void unsetSuccess() {
      __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    public void setSuccessIsSet(boolean value) {
      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
    }

    public org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException getTpe() {
      return this.tpe;
    }

    public updateGateway_result setTpe(org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException tpe) {
      this.tpe = tpe;
      return this;
    }

    public void unsetTpe() {
      this.tpe = null;
    }

    /** Returns true if field tpe is set (has been assigned a value) and false otherwise */
    public boolean isSetTpe() {
      return this.tpe != null;
    }

    public void setTpeIsSet(boolean value) {
      if (!value) {
        this.tpe = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public updateGateway_result setAe(org.apache.airavata.model.error.AuthorizationException ae) {
      this.ae = ae;
      return this;
    }

    public void unsetAe() {
      this.ae = null;
    }

    /** Returns true if field ae is set (has been assigned a value) and false otherwise */
    public boolean isSetAe() {
      return this.ae != null;
    }

    public void setAeIsSet(boolean value) {
      if (!value) {
        this.ae = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.lang.Boolean)value);
        }
        break;

      case TPE:
        if (value == null) {
          unsetTpe();
        } else {
          setTpe((org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return isSuccess();

      case TPE:
        return getTpe();

      case AE:
        return getAe();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case TPE:
        return isSetTpe();
      case AE:
        return isSetAe();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof updateGateway_result)
        return this.equals((updateGateway_result)that);
      return false;
    }

    public boolean equals(updateGateway_result that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_success = true;
      boolean that_present_success = true;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      boolean this_present_tpe = true && this.isSetTpe();
      boolean that_present_tpe = true && that.isSetTpe();
      if (this_present_tpe || that_present_tpe) {
        if (!(this_present_tpe && that_present_tpe))
          return false;
        if (!this.tpe.equals(that.tpe))
          return false;
      }

      boolean this_present_ae = true && this.isSetAe();
      boolean that_present_ae = true && that.isSetAe();
      if (this_present_ae || that_present_ae) {
        if (!(this_present_ae && that_present_ae))
          return false;
        if (!this.ae.equals(that.ae))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((success) ? 131071 : 524287);

      hashCode = hashCode * 8191 + ((isSetTpe()) ? 131071 : 524287);
      if (isSetTpe())
        hashCode = hashCode * 8191 + tpe.hashCode();

      hashCode = hashCode * 8191 + ((isSetAe()) ? 131071 : 524287);
      if (isSetAe())
        hashCode = hashCode * 8191 + ae.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(updateGateway_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetTpe()).compareTo(other.isSetTpe());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetTpe()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.tpe, other.tpe);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetAe()).compareTo(other.isSetAe());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAe()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ae, other.ae);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("updateGateway_result(");
      boolean first = true;

      sb.append("success:");
      sb.append(this.success);
      first = false;
      if (!first) sb.append(", ");
      sb.append("tpe:");
      if (this.tpe == null) {
        sb.append("null");
      } else {
        sb.append(this.tpe);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ae:");
      if (this.ae == null) {
        sb.append("null");
      } else {
        sb.append(this.ae);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor.
        __isset_bitfield = 0;
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class updateGateway_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public updateGateway_resultStandardScheme getScheme() {
        return new updateGateway_resultStandardScheme();
      }
    }

    private static class updateGateway_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<updateGateway_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, updateGateway_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TField schemeField;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
                struct.success = iprot.readBool();
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // TPE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.tpe = new org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException();
                struct.tpe.read(iprot);
                struct.setTpeIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // AE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ae = new org.apache.airavata.model.error.AuthorizationException();
                struct.ae.read(iprot);
                struct.setAeIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, updateGateway_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.isSetSuccess()) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          oprot.writeBool(struct.success);
          oprot.writeFieldEnd();
        }
        if (struct.tpe != null) {
          oprot.writeFieldBegin(TPE_FIELD_DESC);
          struct.tpe.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ae != null) {
          oprot.writeFieldBegin(AE_FIELD_DESC);
          struct.ae.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class updateGateway_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public updateGateway_resultTupleScheme getScheme() {
        return new updateGateway_resultTupleScheme();
      }
    }

    private static class updateGateway_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<updateGateway_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, updateGateway_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet optionals = new java.util.BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetTpe()) {
          optionals.set(1);
        }
        if (struct.isSetAe()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
        if (struct.isSetTpe()) {
          struct.tpe.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, updateGateway_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet incoming = iprot.readBitSet(3);
        if (incoming.get(0)) {
          struct.success = iprot.readBool();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.tpe = new org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException();
          struct.tpe.read(iprot);
          struct.setTpeIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class getGateway_args implements org.apache.thrift.TBase<getGateway_args, getGateway_args._Fields>, java.io.Serializable, Cloneable, Comparable<getGateway_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getGateway_args");

    private static final org.apache.thrift.protocol.TField AUTHZ_TOKEN_FIELD_DESC = new org.apache.thrift.protocol.TField("authzToken", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField AIRAVATA_INTERNAL_GATEWAY_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("airavataInternalGatewayId", org.apache.thrift.protocol.TType.STRING, (short)2);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new getGateway_argsStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new getGateway_argsTupleSchemeFactory();

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public java.lang.String airavataInternalGatewayId; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      AUTHZ_TOKEN((short)1, "authzToken"),
      AIRAVATA_INTERNAL_GATEWAY_ID((short)2, "airavataInternalGatewayId");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // AIRAVATA_INTERNAL_GATEWAY_ID
            return AIRAVATA_INTERNAL_GATEWAY_ID;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.AUTHZ_TOKEN, new org.apache.thrift.meta_data.FieldMetaData("authzToken", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.security.AuthzToken.class)));
      tmpMap.put(_Fields.AIRAVATA_INTERNAL_GATEWAY_ID, new org.apache.thrift.meta_data.FieldMetaData("airavataInternalGatewayId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getGateway_args.class, metaDataMap);
    }

    public getGateway_args() {
    }

    public getGateway_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      java.lang.String airavataInternalGatewayId)
    {
      this();
      this.authzToken = authzToken;
      this.airavataInternalGatewayId = airavataInternalGatewayId;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getGateway_args(getGateway_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetAiravataInternalGatewayId()) {
        this.airavataInternalGatewayId = other.airavataInternalGatewayId;
      }
    }

    public getGateway_args deepCopy() {
      return new getGateway_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.airavataInternalGatewayId = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public getGateway_args setAuthzToken(org.apache.airavata.model.security.AuthzToken authzToken) {
      this.authzToken = authzToken;
      return this;
    }

    public void unsetAuthzToken() {
      this.authzToken = null;
    }

    /** Returns true if field authzToken is set (has been assigned a value) and false otherwise */
    public boolean isSetAuthzToken() {
      return this.authzToken != null;
    }

    public void setAuthzTokenIsSet(boolean value) {
      if (!value) {
        this.authzToken = null;
      }
    }

    public java.lang.String getAiravataInternalGatewayId() {
      return this.airavataInternalGatewayId;
    }

    public getGateway_args setAiravataInternalGatewayId(java.lang.String airavataInternalGatewayId) {
      this.airavataInternalGatewayId = airavataInternalGatewayId;
      return this;
    }

    public void unsetAiravataInternalGatewayId() {
      this.airavataInternalGatewayId = null;
    }

    /** Returns true if field airavataInternalGatewayId is set (has been assigned a value) and false otherwise */
    public boolean isSetAiravataInternalGatewayId() {
      return this.airavataInternalGatewayId != null;
    }

    public void setAiravataInternalGatewayIdIsSet(boolean value) {
      if (!value) {
        this.airavataInternalGatewayId = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case AUTHZ_TOKEN:
        if (value == null) {
          unsetAuthzToken();
        } else {
          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
        }
        break;

      case AIRAVATA_INTERNAL_GATEWAY_ID:
        if (value == null) {
          unsetAiravataInternalGatewayId();
        } else {
          setAiravataInternalGatewayId((java.lang.String)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case AIRAVATA_INTERNAL_GATEWAY_ID:
        return getAiravataInternalGatewayId();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case AIRAVATA_INTERNAL_GATEWAY_ID:
        return isSetAiravataInternalGatewayId();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof getGateway_args)
        return this.equals((getGateway_args)that);
      return false;
    }

    public boolean equals(getGateway_args that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_authzToken = true && this.isSetAuthzToken();
      boolean that_present_authzToken = true && that.isSetAuthzToken();
      if (this_present_authzToken || that_present_authzToken) {
        if (!(this_present_authzToken && that_present_authzToken))
          return false;
        if (!this.authzToken.equals(that.authzToken))
          return false;
      }

      boolean this_present_airavataInternalGatewayId = true && this.isSetAiravataInternalGatewayId();
      boolean that_present_airavataInternalGatewayId = true && that.isSetAiravataInternalGatewayId();
      if (this_present_airavataInternalGatewayId || that_present_airavataInternalGatewayId) {
        if (!(this_present_airavataInternalGatewayId && that_present_airavataInternalGatewayId))
          return false;
        if (!this.airavataInternalGatewayId.equals(that.airavataInternalGatewayId))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetAuthzToken()) ? 131071 : 524287);
      if (isSetAuthzToken())
        hashCode = hashCode * 8191 + authzToken.hashCode();

      hashCode = hashCode * 8191 + ((isSetAiravataInternalGatewayId()) ? 131071 : 524287);
      if (isSetAiravataInternalGatewayId())
        hashCode = hashCode * 8191 + airavataInternalGatewayId.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(getGateway_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetAuthzToken()).compareTo(other.isSetAuthzToken());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAuthzToken()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.authzToken, other.authzToken);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetAiravataInternalGatewayId()).compareTo(other.isSetAiravataInternalGatewayId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAiravataInternalGatewayId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.airavataInternalGatewayId, other.airavataInternalGatewayId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("getGateway_args(");
      boolean first = true;

      sb.append("authzToken:");
      if (this.authzToken == null) {
        sb.append("null");
      } else {
        sb.append(this.authzToken);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("airavataInternalGatewayId:");
      if (this.airavataInternalGatewayId == null) {
        sb.append("null");
      } else {
        sb.append(this.airavataInternalGatewayId);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (authzToken == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'authzToken' was not present! Struct: " + toString());
      }
      if (airavataInternalGatewayId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'airavataInternalGatewayId' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
      if (authzToken != null) {
        authzToken.validate();
      }
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class getGateway_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getGateway_argsStandardScheme getScheme() {
        return new getGateway_argsStandardScheme();
      }
    }

    private static class getGateway_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<getGateway_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getGateway_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TField schemeField;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // AUTHZ_TOKEN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
                struct.authzToken.read(iprot);
                struct.setAuthzTokenIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // AIRAVATA_INTERNAL_GATEWAY_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.airavataInternalGatewayId = iprot.readString();
                struct.setAiravataInternalGatewayIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getGateway_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.authzToken != null) {
          oprot.writeFieldBegin(AUTHZ_TOKEN_FIELD_DESC);
          struct.authzToken.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.airavataInternalGatewayId != null) {
          oprot.writeFieldBegin(AIRAVATA_INTERNAL_GATEWAY_ID_FIELD_DESC);
          oprot.writeString(struct.airavataInternalGatewayId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getGateway_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getGateway_argsTupleScheme getScheme() {
        return new getGateway_argsTupleScheme();
      }
    }

    private static class getGateway_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<getGateway_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getGateway_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.airavataInternalGatewayId);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getGateway_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
        struct.authzToken.read(iprot);
        struct.setAuthzTokenIsSet(true);
        struct.airavataInternalGatewayId = iprot.readString();
        struct.setAiravataInternalGatewayIdIsSet(true);
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class getGateway_result implements org.apache.thrift.TBase<getGateway_result, getGateway_result._Fields>, java.io.Serializable, Cloneable, Comparable<getGateway_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getGateway_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.STRUCT, (short)0);
    private static final org.apache.thrift.protocol.TField TPE_FIELD_DESC = new org.apache.thrift.protocol.TField("tpe", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField AE_FIELD_DESC = new org.apache.thrift.protocol.TField("ae", org.apache.thrift.protocol.TType.STRUCT, (short)2);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new getGateway_resultStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new getGateway_resultTupleSchemeFactory();

    public org.apache.airavata.model.workspace.Gateway success; // required
    public org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException tpe; // required
    public org.apache.airavata.model.error.AuthorizationException ae; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      TPE((short)1, "tpe"),
      AE((short)2, "ae");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // TPE
            return TPE;
          case 2: // AE
            return AE;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.workspace.Gateway.class)));
      tmpMap.put(_Fields.TPE, new org.apache.thrift.meta_data.FieldMetaData("tpe", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException.class)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.error.AuthorizationException.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getGateway_result.class, metaDataMap);
    }

    public getGateway_result() {
    }

    public getGateway_result(
      org.apache.airavata.model.workspace.Gateway success,
      org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException tpe,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      this.tpe = tpe;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getGateway_result(getGateway_result other) {
      if (other.isSetSuccess()) {
        this.success = new org.apache.airavata.model.workspace.Gateway(other.success);
      }
      if (other.isSetTpe()) {
        this.tpe = new org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException(other.tpe);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public getGateway_result deepCopy() {
      return new getGateway_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.tpe = null;
      this.ae = null;
    }

    public org.apache.airavata.model.workspace.Gateway getSuccess() {
      return this.success;
    }

    public getGateway_result setSuccess(org.apache.airavata.model.workspace.Gateway success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return this.success != null;
    }

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException getTpe() {
      return this.tpe;
    }

    public getGateway_result setTpe(org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException tpe) {
      this.tpe = tpe;
      return this;
    }

    public void unsetTpe() {
      this.tpe = null;
    }

    /** Returns true if field tpe is set (has been assigned a value) and false otherwise */
    public boolean isSetTpe() {
      return this.tpe != null;
    }

    public void setTpeIsSet(boolean value) {
      if (!value) {
        this.tpe = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public getGateway_result setAe(org.apache.airavata.model.error.AuthorizationException ae) {
      this.ae = ae;
      return this;
    }

    public void unsetAe() {
      this.ae = null;
    }

    /** Returns true if field ae is set (has been assigned a value) and false otherwise */
    public boolean isSetAe() {
      return this.ae != null;
    }

    public void setAeIsSet(boolean value) {
      if (!value) {
        this.ae = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((org.apache.airavata.model.workspace.Gateway)value);
        }
        break;

      case TPE:
        if (value == null) {
          unsetTpe();
        } else {
          setTpe((org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case TPE:
        return getTpe();

      case AE:
        return getAe();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case TPE:
        return isSetTpe();
      case AE:
        return isSetAe();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof getGateway_result)
        return this.equals((getGateway_result)that);
      return false;
    }

    public boolean equals(getGateway_result that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_tpe = true && this.isSetTpe();
      boolean that_present_tpe = true && that.isSetTpe();
      if (this_present_tpe || that_present_tpe) {
        if (!(this_present_tpe && that_present_tpe))
          return false;
        if (!this.tpe.equals(that.tpe))
          return false;
      }

      boolean this_present_ae = true && this.isSetAe();
      boolean that_present_ae = true && that.isSetAe();
      if (this_present_ae || that_present_ae) {
        if (!(this_present_ae && that_present_ae))
          return false;
        if (!this.ae.equals(that.ae))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
      if (isSetSuccess())
        hashCode = hashCode * 8191 + success.hashCode();

      hashCode = hashCode * 8191 + ((isSetTpe()) ? 131071 : 524287);
      if (isSetTpe())
        hashCode = hashCode * 8191 + tpe.hashCode();

      hashCode = hashCode * 8191 + ((isSetAe()) ? 131071 : 524287);
      if (isSetAe())
        hashCode = hashCode * 8191 + ae.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(getGateway_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetTpe()).compareTo(other.isSetTpe());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetTpe()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.tpe, other.tpe);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetAe()).compareTo(other.isSetAe());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAe()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ae, other.ae);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("getGateway_result(");
      boolean first = true;

      sb.append("success:");
      if (this.success == null) {
        sb.append("null");
      } else {
        sb.append(this.success);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("tpe:");
      if (this.tpe == null) {
        sb.append("null");
      } else {
        sb.append(this.tpe);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ae:");
      if (this.ae == null) {
        sb.append("null");
      } else {
        sb.append(this.ae);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
      if (success != null) {
        success.validate();
      }
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class getGateway_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getGateway_resultStandardScheme getScheme() {
        return new getGateway_resultStandardScheme();
      }
    }

    private static class getGateway_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<getGateway_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getGateway_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TField schemeField;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.success = new org.apache.airavata.model.workspace.Gateway();
                struct.success.read(iprot);
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // TPE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.tpe = new org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException();
                struct.tpe.read(iprot);
                struct.setTpeIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // AE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ae = new org.apache.airavata.model.error.AuthorizationException();
                struct.ae.read(iprot);
                struct.setAeIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getGateway_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          struct.success.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.tpe != null) {
          oprot.writeFieldBegin(TPE_FIELD_DESC);
          struct.tpe.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ae != null) {
          oprot.writeFieldBegin(AE_FIELD_DESC);
          struct.ae.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getGateway_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getGateway_resultTupleScheme getScheme() {
        return new getGateway_resultTupleScheme();
      }
    }

    private static class getGateway_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<getGateway_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getGateway_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet optionals = new java.util.BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetTpe()) {
          optionals.set(1);
        }
        if (struct.isSetAe()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetSuccess()) {
          struct.success.write(oprot);
        }
        if (struct.isSetTpe()) {
          struct.tpe.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getGateway_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet incoming = iprot.readBitSet(3);
        if (incoming.get(0)) {
          struct.success = new org.apache.airavata.model.workspace.Gateway();
          struct.success.read(iprot);
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.tpe = new org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException();
          struct.tpe.read(iprot);
          struct.setTpeIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class deleteGateway_args implements org.apache.thrift.TBase<deleteGateway_args, deleteGateway_args._Fields>, java.io.Serializable, Cloneable, Comparable<deleteGateway_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("deleteGateway_args");

    private static final org.apache.thrift.protocol.TField AUTHZ_TOKEN_FIELD_DESC = new org.apache.thrift.protocol.TField("authzToken", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField AIRAVATA_INTERNAL_GATEWAY_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("airavataInternalGatewayId", org.apache.thrift.protocol.TType.STRING, (short)2);
    private static final org.apache.thrift.protocol.TField GATEWAY_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("gatewayId", org.apache.thrift.protocol.TType.STRING, (short)3);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new deleteGateway_argsStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new deleteGateway_argsTupleSchemeFactory();

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public java.lang.String airavataInternalGatewayId; // required
    public java.lang.String gatewayId; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      AUTHZ_TOKEN((short)1, "authzToken"),
      AIRAVATA_INTERNAL_GATEWAY_ID((short)2, "airavataInternalGatewayId"),
      GATEWAY_ID((short)3, "gatewayId");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // AIRAVATA_INTERNAL_GATEWAY_ID
            return AIRAVATA_INTERNAL_GATEWAY_ID;
          case 3: // GATEWAY_ID
            return GATEWAY_ID;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.AUTHZ_TOKEN, new org.apache.thrift.meta_data.FieldMetaData("authzToken", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.security.AuthzToken.class)));
      tmpMap.put(_Fields.AIRAVATA_INTERNAL_GATEWAY_ID, new org.apache.thrift.meta_data.FieldMetaData("airavataInternalGatewayId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.GATEWAY_ID, new org.apache.thrift.meta_data.FieldMetaData("gatewayId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(deleteGateway_args.class, metaDataMap);
    }

    public deleteGateway_args() {
    }

    public deleteGateway_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      java.lang.String airavataInternalGatewayId,
      java.lang.String gatewayId)
    {
      this();
      this.authzToken = authzToken;
      this.airavataInternalGatewayId = airavataInternalGatewayId;
      this.gatewayId = gatewayId;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public deleteGateway_args(deleteGateway_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetAiravataInternalGatewayId()) {
        this.airavataInternalGatewayId = other.airavataInternalGatewayId;
      }
      if (other.isSetGatewayId()) {
        this.gatewayId = other.gatewayId;
      }
    }

    public deleteGateway_args deepCopy() {
      return new deleteGateway_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.airavataInternalGatewayId = null;
      this.gatewayId = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public deleteGateway_args setAuthzToken(org.apache.airavata.model.security.AuthzToken authzToken) {
      this.authzToken = authzToken;
      return this;
    }

    public void unsetAuthzToken() {
      this.authzToken = null;
    }

    /** Returns true if field authzToken is set (has been assigned a value) and false otherwise */
    public boolean isSetAuthzToken() {
      return this.authzToken != null;
    }

    public void setAuthzTokenIsSet(boolean value) {
      if (!value) {
        this.authzToken = null;
      }
    }

    public java.lang.String getAiravataInternalGatewayId() {
      return this.airavataInternalGatewayId;
    }

    public deleteGateway_args setAiravataInternalGatewayId(java.lang.String airavataInternalGatewayId) {
      this.airavataInternalGatewayId = airavataInternalGatewayId;
      return this;
    }

    public void unsetAiravataInternalGatewayId() {
      this.airavataInternalGatewayId = null;
    }

    /** Returns true if field airavataInternalGatewayId is set (has been assigned a value) and false otherwise */
    public boolean isSetAiravataInternalGatewayId() {
      return this.airavataInternalGatewayId != null;
    }

    public void setAiravataInternalGatewayIdIsSet(boolean value) {
      if (!value) {
        this.airavataInternalGatewayId = null;
      }
    }

    public java.lang.String getGatewayId() {
      return this.gatewayId;
    }

    public deleteGateway_args setGatewayId(java.lang.String gatewayId) {
      this.gatewayId = gatewayId;
      return this;
    }

    public void unsetGatewayId() {
      this.gatewayId = null;
    }

    /** Returns true if field gatewayId is set (has been assigned a value) and false otherwise */
    public boolean isSetGatewayId() {
      return this.gatewayId != null;
    }

    public void setGatewayIdIsSet(boolean value) {
      if (!value) {
        this.gatewayId = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case AUTHZ_TOKEN:
        if (value == null) {
          unsetAuthzToken();
        } else {
          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
        }
        break;

      case AIRAVATA_INTERNAL_GATEWAY_ID:
        if (value == null) {
          unsetAiravataInternalGatewayId();
        } else {
          setAiravataInternalGatewayId((java.lang.String)value);
        }
        break;

      case GATEWAY_ID:
        if (value == null) {
          unsetGatewayId();
        } else {
          setGatewayId((java.lang.String)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case AIRAVATA_INTERNAL_GATEWAY_ID:
        return getAiravataInternalGatewayId();

      case GATEWAY_ID:
        return getGatewayId();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case AIRAVATA_INTERNAL_GATEWAY_ID:
        return isSetAiravataInternalGatewayId();
      case GATEWAY_ID:
        return isSetGatewayId();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof deleteGateway_args)
        return this.equals((deleteGateway_args)that);
      return false;
    }

    public boolean equals(deleteGateway_args that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_authzToken = true && this.isSetAuthzToken();
      boolean that_present_authzToken = true && that.isSetAuthzToken();
      if (this_present_authzToken || that_present_authzToken) {
        if (!(this_present_authzToken && that_present_authzToken))
          return false;
        if (!this.authzToken.equals(that.authzToken))
          return false;
      }

      boolean this_present_airavataInternalGatewayId = true && this.isSetAiravataInternalGatewayId();
      boolean that_present_airavataInternalGatewayId = true && that.isSetAiravataInternalGatewayId();
      if (this_present_airavataInternalGatewayId || that_present_airavataInternalGatewayId) {
        if (!(this_present_airavataInternalGatewayId && that_present_airavataInternalGatewayId))
          return false;
        if (!this.airavataInternalGatewayId.equals(that.airavataInternalGatewayId))
          return false;
      }

      boolean this_present_gatewayId = true && this.isSetGatewayId();
      boolean that_present_gatewayId = true && that.isSetGatewayId();
      if (this_present_gatewayId || that_present_gatewayId) {
        if (!(this_present_gatewayId && that_present_gatewayId))
          return false;
        if (!this.gatewayId.equals(that.gatewayId))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetAuthzToken()) ? 131071 : 524287);
      if (isSetAuthzToken())
        hashCode = hashCode * 8191 + authzToken.hashCode();

      hashCode = hashCode * 8191 + ((isSetAiravataInternalGatewayId()) ? 131071 : 524287);
      if (isSetAiravataInternalGatewayId())
        hashCode = hashCode * 8191 + airavataInternalGatewayId.hashCode();

      hashCode = hashCode * 8191 + ((isSetGatewayId()) ? 131071 : 524287);
      if (isSetGatewayId())
        hashCode = hashCode * 8191 + gatewayId.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(deleteGateway_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetAuthzToken()).compareTo(other.isSetAuthzToken());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAuthzToken()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.authzToken, other.authzToken);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetAiravataInternalGatewayId()).compareTo(other.isSetAiravataInternalGatewayId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAiravataInternalGatewayId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.airavataInternalGatewayId, other.airavataInternalGatewayId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetGatewayId()).compareTo(other.isSetGatewayId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetGatewayId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.gatewayId, other.gatewayId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("deleteGateway_args(");
      boolean first = true;

      sb.append("authzToken:");
      if (this.authzToken == null) {
        sb.append("null");
      } else {
        sb.append(this.authzToken);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("airavataInternalGatewayId:");
      if (this.airavataInternalGatewayId == null) {
        sb.append("null");
      } else {
        sb.append(this.airavataInternalGatewayId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("gatewayId:");
      if (this.gatewayId == null) {
        sb.append("null");
      } else {
        sb.append(this.gatewayId);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (authzToken == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'authzToken' was not present! Struct: " + toString());
      }
      if (airavataInternalGatewayId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'airavataInternalGatewayId' was not present! Struct: " + toString());
      }
      if (gatewayId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'gatewayId' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
      if (authzToken != null) {
        authzToken.validate();
      }
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class deleteGateway_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public deleteGateway_argsStandardScheme getScheme() {
        return new deleteGateway_argsStandardScheme();
      }
    }

    private static class deleteGateway_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<deleteGateway_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, deleteGateway_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TField schemeField;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // AUTHZ_TOKEN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
                struct.authzToken.read(iprot);
                struct.setAuthzTokenIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // AIRAVATA_INTERNAL_GATEWAY_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.airavataInternalGatewayId = iprot.readString();
                struct.setAiravataInternalGatewayIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // GATEWAY_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.gatewayId = iprot.readString();
                struct.setGatewayIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, deleteGateway_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.authzToken != null) {
          oprot.writeFieldBegin(AUTHZ_TOKEN_FIELD_DESC);
          struct.authzToken.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.airavataInternalGatewayId != null) {
          oprot.writeFieldBegin(AIRAVATA_INTERNAL_GATEWAY_ID_FIELD_DESC);
          oprot.writeString(struct.airavataInternalGatewayId);
          oprot.writeFieldEnd();
        }
        if (struct.gatewayId != null) {
          oprot.writeFieldBegin(GATEWAY_ID_FIELD_DESC);
          oprot.writeString(struct.gatewayId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class deleteGateway_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public deleteGateway_argsTupleScheme getScheme() {
        return new deleteGateway_argsTupleScheme();
      }
    }

    private static class deleteGateway_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<deleteGateway_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, deleteGateway_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.airavataInternalGatewayId);
        oprot.writeString(struct.gatewayId);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, deleteGateway_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
        struct.authzToken.read(iprot);
        struct.setAuthzTokenIsSet(true);
        struct.airavataInternalGatewayId = iprot.readString();
        struct.setAiravataInternalGatewayIdIsSet(true);
        struct.gatewayId = iprot.readString();
        struct.setGatewayIdIsSet(true);
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class deleteGateway_result implements org.apache.thrift.TBase<deleteGateway_result, deleteGateway_result._Fields>, java.io.Serializable, Cloneable, Comparable<deleteGateway_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("deleteGateway_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.BOOL, (short)0);
    private static final org.apache.thrift.protocol.TField TPE_FIELD_DESC = new org.apache.thrift.protocol.TField("tpe", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField AE_FIELD_DESC = new org.apache.thrift.protocol.TField("ae", org.apache.thrift.protocol.TType.STRUCT, (short)2);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new deleteGateway_resultStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new deleteGateway_resultTupleSchemeFactory();

    public boolean success; // required
    public org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException tpe; // required
    public org.apache.airavata.model.error.AuthorizationException ae; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      TPE((short)1, "tpe"),
      AE((short)2, "ae");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // TPE
            return TPE;
          case 2: // AE
            return AE;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __SUCCESS_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
      tmpMap.put(_Fields.TPE, new org.apache.thrift.meta_data.FieldMetaData("tpe", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException.class)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.error.AuthorizationException.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(deleteGateway_result.class, metaDataMap);
    }

    public deleteGateway_result() {
    }

    public deleteGateway_result(
      boolean success,
      org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException tpe,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
      this.tpe = tpe;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public deleteGateway_result(deleteGateway_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
      if (other.isSetTpe()) {
        this.tpe = new org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException(other.tpe);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public deleteGateway_result deepCopy() {
      return new deleteGateway_result(this);
    }

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
      this.tpe = null;
      this.ae = null;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public deleteGateway_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

    public void unsetSuccess() {
      __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    public void setSuccessIsSet(boolean value) {
      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
    }

    public org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException getTpe() {
      return this.tpe;
    }

    public deleteGateway_result setTpe(org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException tpe) {
      this.tpe = tpe;
      return this;
    }

    public void unsetTpe() {
      this.tpe = null;
    }

    /** Returns true if field tpe is set (has been assigned a value) and false otherwise */
    public boolean isSetTpe() {
      return this.tpe != null;
    }

    public void setTpeIsSet(boolean value) {
      if (!value) {
        this.tpe = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public deleteGateway_result setAe(org.apache.airavata.model.error.AuthorizationException ae) {
      this.ae = ae;
      return this;
    }

    public void unsetAe() {
      this.ae = null;
    }

    /** Returns true if field ae is set (has been assigned a value) and false otherwise */
    public boolean isSetAe() {
      return this.ae != null;
    }

    public void setAeIsSet(boolean value) {
      if (!value) {
        this.ae = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.lang.Boolean)value);
        }
        break;

      case TPE:
        if (value == null) {
          unsetTpe();
        } else {
          setTpe((org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return isSuccess();

      case TPE:
        return getTpe();

      case AE:
        return getAe();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case TPE:
        return isSetTpe();
      case AE:
        return isSetAe();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof deleteGateway_result)
        return this.equals((deleteGateway_result)that);
      return false;
    }

    public boolean equals(deleteGateway_result that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_success = true;
      boolean that_present_success = true;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      boolean this_present_tpe = true && this.isSetTpe();
      boolean that_present_tpe = true && that.isSetTpe();
      if (this_present_tpe || that_present_tpe) {
        if (!(this_present_tpe && that_present_tpe))
          return false;
        if (!this.tpe.equals(that.tpe))
          return false;
      }

      boolean this_present_ae = true && this.isSetAe();
      boolean that_present_ae = true && that.isSetAe();
      if (this_present_ae || that_present_ae) {
        if (!(this_present_ae && that_present_ae))
          return false;
        if (!this.ae.equals(that.ae))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((success) ? 131071 : 524287);

      hashCode = hashCode * 8191 + ((isSetTpe()) ? 131071 : 524287);
      if (isSetTpe())
        hashCode = hashCode * 8191 + tpe.hashCode();

      hashCode = hashCode * 8191 + ((isSetAe()) ? 131071 : 524287);
      if (isSetAe())
        hashCode = hashCode * 8191 + ae.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(deleteGateway_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetTpe()).compareTo(other.isSetTpe());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetTpe()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.tpe, other.tpe);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetAe()).compareTo(other.isSetAe());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAe()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ae, other.ae);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("deleteGateway_result(");
      boolean first = true;

      sb.append("success:");
      sb.append(this.success);
      first = false;
      if (!first) sb.append(", ");
      sb.append("tpe:");
      if (this.tpe == null) {
        sb.append("null");
      } else {
        sb.append(this.tpe);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ae:");
      if (this.ae == null) {
        sb.append("null");
      } else {
        sb.append(this.ae);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor.
        __isset_bitfield = 0;
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class deleteGateway_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public deleteGateway_resultStandardScheme getScheme() {
        return new deleteGateway_resultStandardScheme();
      }
    }

    private static class deleteGateway_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<deleteGateway_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, deleteGateway_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TField schemeField;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
                struct.success = iprot.readBool();
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // TPE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.tpe = new org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException();
                struct.tpe.read(iprot);
                struct.setTpeIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // AE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ae = new org.apache.airavata.model.error.AuthorizationException();
                struct.ae.read(iprot);
                struct.setAeIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, deleteGateway_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.isSetSuccess()) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          oprot.writeBool(struct.success);
          oprot.writeFieldEnd();
        }
        if (struct.tpe != null) {
          oprot.writeFieldBegin(TPE_FIELD_DESC);
          struct.tpe.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ae != null) {
          oprot.writeFieldBegin(AE_FIELD_DESC);
          struct.ae.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class deleteGateway_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public deleteGateway_resultTupleScheme getScheme() {
        return new deleteGateway_resultTupleScheme();
      }
    }

    private static class deleteGateway_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<deleteGateway_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, deleteGateway_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet optionals = new java.util.BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetTpe()) {
          optionals.set(1);
        }
        if (struct.isSetAe()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
        if (struct.isSetTpe()) {
          struct.tpe.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, deleteGateway_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet incoming = iprot.readBitSet(3);
        if (incoming.get(0)) {
          struct.success = iprot.readBool();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.tpe = new org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException();
          struct.tpe.read(iprot);
          struct.setTpeIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class getAllGateways_args implements org.apache.thrift.TBase<getAllGateways_args, getAllGateways_args._Fields>, java.io.Serializable, Cloneable, Comparable<getAllGateways_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getAllGateways_args");

    private static final org.apache.thrift.protocol.TField AUTHZ_TOKEN_FIELD_DESC = new org.apache.thrift.protocol.TField("authzToken", org.apache.thrift.protocol.TType.STRUCT, (short)1);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new getAllGateways_argsStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new getAllGateways_argsTupleSchemeFactory();

    public org.apache.airavata.model.security.AuthzToken authzToken; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      AUTHZ_TOKEN((short)1, "authzToken");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.AUTHZ_TOKEN, new org.apache.thrift.meta_data.FieldMetaData("authzToken", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.security.AuthzToken.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getAllGateways_args.class, metaDataMap);
    }

    public getAllGateways_args() {
    }

    public getAllGateways_args(
      org.apache.airavata.model.security.AuthzToken authzToken)
    {
      this();
      this.authzToken = authzToken;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getAllGateways_args(getAllGateways_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
    }

    public getAllGateways_args deepCopy() {
      return new getAllGateways_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public getAllGateways_args setAuthzToken(org.apache.airavata.model.security.AuthzToken authzToken) {
      this.authzToken = authzToken;
      return this;
    }

    public void unsetAuthzToken() {
      this.authzToken = null;
    }

    /** Returns true if field authzToken is set (has been assigned a value) and false otherwise */
    public boolean isSetAuthzToken() {
      return this.authzToken != null;
    }

    public void setAuthzTokenIsSet(boolean value) {
      if (!value) {
        this.authzToken = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case AUTHZ_TOKEN:
        if (value == null) {
          unsetAuthzToken();
        } else {
          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof getAllGateways_args)
        return this.equals((getAllGateways_args)that);
      return false;
    }

    public boolean equals(getAllGateways_args that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_authzToken = true && this.isSetAuthzToken();
      boolean that_present_authzToken = true && that.isSetAuthzToken();
      if (this_present_authzToken || that_present_authzToken) {
        if (!(this_present_authzToken && that_present_authzToken))
          return false;
        if (!this.authzToken.equals(that.authzToken))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetAuthzToken()) ? 131071 : 524287);
      if (isSetAuthzToken())
        hashCode = hashCode * 8191 + authzToken.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(getAllGateways_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetAuthzToken()).compareTo(other.isSetAuthzToken());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAuthzToken()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.authzToken, other.authzToken);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("getAllGateways_args(");
      boolean first = true;

      sb.append("authzToken:");
      if (this.authzToken == null) {
        sb.append("null");
      } else {
        sb.append(this.authzToken);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (authzToken == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'authzToken' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
      if (authzToken != null) {
        authzToken.validate();
      }
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class getAllGateways_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getAllGateways_argsStandardScheme getScheme() {
        return new getAllGateways_argsStandardScheme();
      }
    }

    private static class getAllGateways_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<getAllGateways_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getAllGateways_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TField schemeField;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // AUTHZ_TOKEN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
                struct.authzToken.read(iprot);
                struct.setAuthzTokenIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getAllGateways_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.authzToken != null) {
          oprot.writeFieldBegin(AUTHZ_TOKEN_FIELD_DESC);
          struct.authzToken.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getAllGateways_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getAllGateways_argsTupleScheme getScheme() {
        return new getAllGateways_argsTupleScheme();
      }
    }

    private static class getAllGateways_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<getAllGateways_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getAllGateways_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.authzToken.write(oprot);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getAllGateways_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
        struct.authzToken.read(iprot);
        struct.setAuthzTokenIsSet(true);
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class getAllGateways_result implements org.apache.thrift.TBase<getAllGateways_result, getAllGateways_result._Fields>, java.io.Serializable, Cloneable, Comparable<getAllGateways_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getAllGateways_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.LIST, (short)0);
    private static final org.apache.thrift.protocol.TField TPE_FIELD_DESC = new org.apache.thrift.protocol.TField("tpe", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField AE_FIELD_DESC = new org.apache.thrift.protocol.TField("ae", org.apache.thrift.protocol.TType.STRUCT, (short)2);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new getAllGateways_resultStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new getAllGateways_resultTupleSchemeFactory();

    public java.util.List<org.apache.airavata.model.workspace.Gateway> success; // required
    public org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException tpe; // required
    public org.apache.airavata.model.error.AuthorizationException ae; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      TPE((short)1, "tpe"),
      AE((short)2, "ae");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // TPE
            return TPE;
          case 2: // AE
            return AE;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
              new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.workspace.Gateway.class))));
      tmpMap.put(_Fields.TPE, new org.apache.thrift.meta_data.FieldMetaData("tpe", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException.class)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.error.AuthorizationException.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getAllGateways_result.class, metaDataMap);
    }

    public getAllGateways_result() {
    }

    public getAllGateways_result(
      java.util.List<org.apache.airavata.model.workspace.Gateway> success,
      org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException tpe,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      this.tpe = tpe;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getAllGateways_result(getAllGateways_result other) {
      if (other.isSetSuccess()) {
        java.util.List<org.apache.airavata.model.workspace.Gateway> __this__success = new java.util.ArrayList<org.apache.airavata.model.workspace.Gateway>(other.success.size());
        for (org.apache.airavata.model.workspace.Gateway other_element : other.success) {
          __this__success.add(new org.apache.airavata.model.workspace.Gateway(other_element));
        }
        this.success = __this__success;
      }
      if (other.isSetTpe()) {
        this.tpe = new org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException(other.tpe);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public getAllGateways_result deepCopy() {
      return new getAllGateways_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.tpe = null;
      this.ae = null;
    }

    public int getSuccessSize() {
      return (this.success == null) ? 0 : this.success.size();
    }

    public java.util.Iterator<org.apache.airavata.model.workspace.Gateway> getSuccessIterator() {
      return (this.success == null) ? null : this.success.iterator();
    }

    public void addToSuccess(org.apache.airavata.model.workspace.Gateway elem) {
      if (this.success == null) {
        this.success = new java.util.ArrayList<org.apache.airavata.model.workspace.Gateway>();
      }
      this.success.add(elem);
    }

    public java.util.List<org.apache.airavata.model.workspace.Gateway> getSuccess() {
      return this.success;
    }

    public getAllGateways_result setSuccess(java.util.List<org.apache.airavata.model.workspace.Gateway> success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return this.success != null;
    }

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException getTpe() {
      return this.tpe;
    }

    public getAllGateways_result setTpe(org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException tpe) {
      this.tpe = tpe;
      return this;
    }

    public void unsetTpe() {
      this.tpe = null;
    }

    /** Returns true if field tpe is set (has been assigned a value) and false otherwise */
    public boolean isSetTpe() {
      return this.tpe != null;
    }

    public void setTpeIsSet(boolean value) {
      if (!value) {
        this.tpe = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public getAllGateways_result setAe(org.apache.airavata.model.error.AuthorizationException ae) {
      this.ae = ae;
      return this;
    }

    public void unsetAe() {
      this.ae = null;
    }

    /** Returns true if field ae is set (has been assigned a value) and false otherwise */
    public boolean isSetAe() {
      return this.ae != null;
    }

    public void setAeIsSet(boolean value) {
      if (!value) {
        this.ae = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.util.List<org.apache.airavata.model.workspace.Gateway>)value);
        }
        break;

      case TPE:
        if (value == null) {
          unsetTpe();
        } else {
          setTpe((org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case TPE:
        return getTpe();

      case AE:
        return getAe();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case TPE:
        return isSetTpe();
      case AE:
        return isSetAe();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof getAllGateways_result)
        return this.equals((getAllGateways_result)that);
      return false;
    }

    public boolean equals(getAllGateways_result that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_tpe = true && this.isSetTpe();
      boolean that_present_tpe = true && that.isSetTpe();
      if (this_present_tpe || that_present_tpe) {
        if (!(this_present_tpe && that_present_tpe))
          return false;
        if (!this.tpe.equals(that.tpe))
          return false;
      }

      boolean this_present_ae = true && this.isSetAe();
      boolean that_present_ae = true && that.isSetAe();
      if (this_present_ae || that_present_ae) {
        if (!(this_present_ae && that_present_ae))
          return false;
        if (!this.ae.equals(that.ae))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
      if (isSetSuccess())
        hashCode = hashCode * 8191 + success.hashCode();

      hashCode = hashCode * 8191 + ((isSetTpe()) ? 131071 : 524287);
      if (isSetTpe())
        hashCode = hashCode * 8191 + tpe.hashCode();

      hashCode = hashCode * 8191 + ((isSetAe()) ? 131071 : 524287);
      if (isSetAe())
        hashCode = hashCode * 8191 + ae.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(getAllGateways_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetTpe()).compareTo(other.isSetTpe());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetTpe()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.tpe, other.tpe);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetAe()).compareTo(other.isSetAe());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAe()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ae, other.ae);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("getAllGateways_result(");
      boolean first = true;

      sb.append("success:");
      if (this.success == null) {
        sb.append("null");
      } else {
        sb.append(this.success);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("tpe:");
      if (this.tpe == null) {
        sb.append("null");
      } else {
        sb.append(this.tpe);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ae:");
      if (this.ae == null) {
        sb.append("null");
      } else {
        sb.append(this.ae);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class getAllGateways_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getAllGateways_resultStandardScheme getScheme() {
        return new getAllGateways_resultStandardScheme();
      }
    }

    private static class getAllGateways_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<getAllGateways_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getAllGateways_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TField schemeField;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
                {
                  org.apache.thrift.protocol.TList _list0 = iprot.readListBegin();
                  struct.success = new java.util.ArrayList<org.apache.airavata.model.workspace.Gateway>(_list0.size);
                  org.apache.airavata.model.workspace.Gateway _elem1;
                  for (int _i2 = 0; _i2 < _list0.size; ++_i2)
                  {
                    _elem1 = new org.apache.airavata.model.workspace.Gateway();
                    _elem1.read(iprot);
                    struct.success.add(_elem1);
                  }
                  iprot.readListEnd();
                }
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // TPE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.tpe = new org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException();
                struct.tpe.read(iprot);
                struct.setTpeIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // AE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ae = new org.apache.airavata.model.error.AuthorizationException();
                struct.ae.read(iprot);
                struct.setAeIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getAllGateways_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, struct.success.size()));
            for (org.apache.airavata.model.workspace.Gateway _iter3 : struct.success)
            {
              _iter3.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.tpe != null) {
          oprot.writeFieldBegin(TPE_FIELD_DESC);
          struct.tpe.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ae != null) {
          oprot.writeFieldBegin(AE_FIELD_DESC);
          struct.ae.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getAllGateways_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getAllGateways_resultTupleScheme getScheme() {
        return new getAllGateways_resultTupleScheme();
      }
    }

    private static class getAllGateways_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<getAllGateways_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getAllGateways_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet optionals = new java.util.BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetTpe()) {
          optionals.set(1);
        }
        if (struct.isSetAe()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetSuccess()) {
          {
            oprot.writeI32(struct.success.size());
            for (org.apache.airavata.model.workspace.Gateway _iter4 : struct.success)
            {
              _iter4.write(oprot);
            }
          }
        }
        if (struct.isSetTpe()) {
          struct.tpe.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getAllGateways_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet incoming = iprot.readBitSet(3);
        if (incoming.get(0)) {
          {
            org.apache.thrift.protocol.TList _list5 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
            struct.success = new java.util.ArrayList<org.apache.airavata.model.workspace.Gateway>(_list5.size);
            org.apache.airavata.model.workspace.Gateway _elem6;
            for (int _i7 = 0; _i7 < _list5.size; ++_i7)
            {
              _elem6 = new org.apache.airavata.model.workspace.Gateway();
              _elem6.read(iprot);
              struct.success.add(_elem6);
            }
          }
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.tpe = new org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException();
          struct.tpe.read(iprot);
          struct.setTpeIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class isGatewayExist_args implements org.apache.thrift.TBase<isGatewayExist_args, isGatewayExist_args._Fields>, java.io.Serializable, Cloneable, Comparable<isGatewayExist_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("isGatewayExist_args");

    private static final org.apache.thrift.protocol.TField AUTHZ_TOKEN_FIELD_DESC = new org.apache.thrift.protocol.TField("authzToken", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField GATEWAY_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("gatewayId", org.apache.thrift.protocol.TType.STRING, (short)2);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new isGatewayExist_argsStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new isGatewayExist_argsTupleSchemeFactory();

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public java.lang.String gatewayId; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      AUTHZ_TOKEN((short)1, "authzToken"),
      GATEWAY_ID((short)2, "gatewayId");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // GATEWAY_ID
            return GATEWAY_ID;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.AUTHZ_TOKEN, new org.apache.thrift.meta_data.FieldMetaData("authzToken", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.security.AuthzToken.class)));
      tmpMap.put(_Fields.GATEWAY_ID, new org.apache.thrift.meta_data.FieldMetaData("gatewayId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(isGatewayExist_args.class, metaDataMap);
    }

    public isGatewayExist_args() {
    }

    public isGatewayExist_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      java.lang.String gatewayId)
    {
      this();
      this.authzToken = authzToken;
      this.gatewayId = gatewayId;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public isGatewayExist_args(isGatewayExist_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetGatewayId()) {
        this.gatewayId = other.gatewayId;
      }
    }

    public isGatewayExist_args deepCopy() {
      return new isGatewayExist_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.gatewayId = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public isGatewayExist_args setAuthzToken(org.apache.airavata.model.security.AuthzToken authzToken) {
      this.authzToken = authzToken;
      return this;
    }

    public void unsetAuthzToken() {
      this.authzToken = null;
    }

    /** Returns true if field authzToken is set (has been assigned a value) and false otherwise */
    public boolean isSetAuthzToken() {
      return this.authzToken != null;
    }

    public void setAuthzTokenIsSet(boolean value) {
      if (!value) {
        this.authzToken = null;
      }
    }

    public java.lang.String getGatewayId() {
      return this.gatewayId;
    }

    public isGatewayExist_args setGatewayId(java.lang.String gatewayId) {
      this.gatewayId = gatewayId;
      return this;
    }

    public void unsetGatewayId() {
      this.gatewayId = null;
    }

    /** Returns true if field gatewayId is set (has been assigned a value) and false otherwise */
    public boolean isSetGatewayId() {
      return this.gatewayId != null;
    }

    public void setGatewayIdIsSet(boolean value) {
      if (!value) {
        this.gatewayId = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case AUTHZ_TOKEN:
        if (value == null) {
          unsetAuthzToken();
        } else {
          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
        }
        break;

      case GATEWAY_ID:
        if (value == null) {
          unsetGatewayId();
        } else {
          setGatewayId((java.lang.String)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case GATEWAY_ID:
        return getGatewayId();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case GATEWAY_ID:
        return isSetGatewayId();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof isGatewayExist_args)
        return this.equals((isGatewayExist_args)that);
      return false;
    }

    public boolean equals(isGatewayExist_args that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_authzToken = true && this.isSetAuthzToken();
      boolean that_present_authzToken = true && that.isSetAuthzToken();
      if (this_present_authzToken || that_present_authzToken) {
        if (!(this_present_authzToken && that_present_authzToken))
          return false;
        if (!this.authzToken.equals(that.authzToken))
          return false;
      }

      boolean this_present_gatewayId = true && this.isSetGatewayId();
      boolean that_present_gatewayId = true && that.isSetGatewayId();
      if (this_present_gatewayId || that_present_gatewayId) {
        if (!(this_present_gatewayId && that_present_gatewayId))
          return false;
        if (!this.gatewayId.equals(that.gatewayId))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetAuthzToken()) ? 131071 : 524287);
      if (isSetAuthzToken())
        hashCode = hashCode * 8191 + authzToken.hashCode();

      hashCode = hashCode * 8191 + ((isSetGatewayId()) ? 131071 : 524287);
      if (isSetGatewayId())
        hashCode = hashCode * 8191 + gatewayId.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(isGatewayExist_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetAuthzToken()).compareTo(other.isSetAuthzToken());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAuthzToken()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.authzToken, other.authzToken);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetGatewayId()).compareTo(other.isSetGatewayId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetGatewayId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.gatewayId, other.gatewayId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("isGatewayExist_args(");
      boolean first = true;

      sb.append("authzToken:");
      if (this.authzToken == null) {
        sb.append("null");
      } else {
        sb.append(this.authzToken);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("gatewayId:");
      if (this.gatewayId == null) {
        sb.append("null");
      } else {
        sb.append(this.gatewayId);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (authzToken == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'authzToken' was not present! Struct: " + toString());
      }
      if (gatewayId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'gatewayId' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
      if (authzToken != null) {
        authzToken.validate();
      }
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class isGatewayExist_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public isGatewayExist_argsStandardScheme getScheme() {
        return new isGatewayExist_argsStandardScheme();
      }
    }

    private static class isGatewayExist_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<isGatewayExist_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, isGatewayExist_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TField schemeField;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // AUTHZ_TOKEN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
                struct.authzToken.read(iprot);
                struct.setAuthzTokenIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // GATEWAY_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.gatewayId = iprot.readString();
                struct.setGatewayIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, isGatewayExist_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.authzToken != null) {
          oprot.writeFieldBegin(AUTHZ_TOKEN_FIELD_DESC);
          struct.authzToken.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.gatewayId != null) {
          oprot.writeFieldBegin(GATEWAY_ID_FIELD_DESC);
          oprot.writeString(struct.gatewayId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class isGatewayExist_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public isGatewayExist_argsTupleScheme getScheme() {
        return new isGatewayExist_argsTupleScheme();
      }
    }

    private static class isGatewayExist_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<isGatewayExist_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, isGatewayExist_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.gatewayId);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, isGatewayExist_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
        struct.authzToken.read(iprot);
        struct.setAuthzTokenIsSet(true);
        struct.gatewayId = iprot.readString();
        struct.setGatewayIdIsSet(true);
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class isGatewayExist_result implements org.apache.thrift.TBase<isGatewayExist_result, isGatewayExist_result._Fields>, java.io.Serializable, Cloneable, Comparable<isGatewayExist_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("isGatewayExist_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.BOOL, (short)0);
    private static final org.apache.thrift.protocol.TField TPE_FIELD_DESC = new org.apache.thrift.protocol.TField("tpe", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField AE_FIELD_DESC = new org.apache.thrift.protocol.TField("ae", org.apache.thrift.protocol.TType.STRUCT, (short)2);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new isGatewayExist_resultStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new isGatewayExist_resultTupleSchemeFactory();

    public boolean success; // required
    public org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException tpe; // required
    public org.apache.airavata.model.error.AuthorizationException ae; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      TPE((short)1, "tpe"),
      AE((short)2, "ae");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // TPE
            return TPE;
          case 2: // AE
            return AE;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __SUCCESS_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
      tmpMap.put(_Fields.TPE, new org.apache.thrift.meta_data.FieldMetaData("tpe", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException.class)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.error.AuthorizationException.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(isGatewayExist_result.class, metaDataMap);
    }

    public isGatewayExist_result() {
    }

    public isGatewayExist_result(
      boolean success,
      org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException tpe,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
      this.tpe = tpe;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public isGatewayExist_result(isGatewayExist_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
      if (other.isSetTpe()) {
        this.tpe = new org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException(other.tpe);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public isGatewayExist_result deepCopy() {
      return new isGatewayExist_result(this);
    }

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
      this.tpe = null;
      this.ae = null;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public isGatewayExist_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

    public void unsetSuccess() {
      __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    public void setSuccessIsSet(boolean value) {
      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
    }

    public org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException getTpe() {
      return this.tpe;
    }

    public isGatewayExist_result setTpe(org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException tpe) {
      this.tpe = tpe;
      return this;
    }

    public void unsetTpe() {
      this.tpe = null;
    }

    /** Returns true if field tpe is set (has been assigned a value) and false otherwise */
    public boolean isSetTpe() {
      return this.tpe != null;
    }

    public void setTpeIsSet(boolean value) {
      if (!value) {
        this.tpe = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public isGatewayExist_result setAe(org.apache.airavata.model.error.AuthorizationException ae) {
      this.ae = ae;
      return this;
    }

    public void unsetAe() {
      this.ae = null;
    }

    /** Returns true if field ae is set (has been assigned a value) and false otherwise */
    public boolean isSetAe() {
      return this.ae != null;
    }

    public void setAeIsSet(boolean value) {
      if (!value) {
        this.ae = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.lang.Boolean)value);
        }
        break;

      case TPE:
        if (value == null) {
          unsetTpe();
        } else {
          setTpe((org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return isSuccess();

      case TPE:
        return getTpe();

      case AE:
        return getAe();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case TPE:
        return isSetTpe();
      case AE:
        return isSetAe();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof isGatewayExist_result)
        return this.equals((isGatewayExist_result)that);
      return false;
    }

    public boolean equals(isGatewayExist_result that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_success = true;
      boolean that_present_success = true;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      boolean this_present_tpe = true && this.isSetTpe();
      boolean that_present_tpe = true && that.isSetTpe();
      if (this_present_tpe || that_present_tpe) {
        if (!(this_present_tpe && that_present_tpe))
          return false;
        if (!this.tpe.equals(that.tpe))
          return false;
      }

      boolean this_present_ae = true && this.isSetAe();
      boolean that_present_ae = true && that.isSetAe();
      if (this_present_ae || that_present_ae) {
        if (!(this_present_ae && that_present_ae))
          return false;
        if (!this.ae.equals(that.ae))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((success) ? 131071 : 524287);

      hashCode = hashCode * 8191 + ((isSetTpe()) ? 131071 : 524287);
      if (isSetTpe())
        hashCode = hashCode * 8191 + tpe.hashCode();

      hashCode = hashCode * 8191 + ((isSetAe()) ? 131071 : 524287);
      if (isSetAe())
        hashCode = hashCode * 8191 + ae.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(isGatewayExist_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetTpe()).compareTo(other.isSetTpe());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetTpe()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.tpe, other.tpe);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetAe()).compareTo(other.isSetAe());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAe()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ae, other.ae);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("isGatewayExist_result(");
      boolean first = true;

      sb.append("success:");
      sb.append(this.success);
      first = false;
      if (!first) sb.append(", ");
      sb.append("tpe:");
      if (this.tpe == null) {
        sb.append("null");
      } else {
        sb.append(this.tpe);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ae:");
      if (this.ae == null) {
        sb.append("null");
      } else {
        sb.append(this.ae);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor.
        __isset_bitfield = 0;
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class isGatewayExist_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public isGatewayExist_resultStandardScheme getScheme() {
        return new isGatewayExist_resultStandardScheme();
      }
    }

    private static class isGatewayExist_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<isGatewayExist_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, isGatewayExist_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TField schemeField;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
                struct.success = iprot.readBool();
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // TPE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.tpe = new org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException();
                struct.tpe.read(iprot);
                struct.setTpeIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // AE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ae = new org.apache.airavata.model.error.AuthorizationException();
                struct.ae.read(iprot);
                struct.setAeIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, isGatewayExist_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.isSetSuccess()) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          oprot.writeBool(struct.success);
          oprot.writeFieldEnd();
        }
        if (struct.tpe != null) {
          oprot.writeFieldBegin(TPE_FIELD_DESC);
          struct.tpe.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ae != null) {
          oprot.writeFieldBegin(AE_FIELD_DESC);
          struct.ae.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class isGatewayExist_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public isGatewayExist_resultTupleScheme getScheme() {
        return new isGatewayExist_resultTupleScheme();
      }
    }

    private static class isGatewayExist_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<isGatewayExist_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, isGatewayExist_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet optionals = new java.util.BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetTpe()) {
          optionals.set(1);
        }
        if (struct.isSetAe()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
        if (struct.isSetTpe()) {
          struct.tpe.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, isGatewayExist_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet incoming = iprot.readBitSet(3);
        if (incoming.get(0)) {
          struct.success = iprot.readBool();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.tpe = new org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException();
          struct.tpe.read(iprot);
          struct.setTpeIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class getAllGatewaysForUser_args implements org.apache.thrift.TBase<getAllGatewaysForUser_args, getAllGatewaysForUser_args._Fields>, java.io.Serializable, Cloneable, Comparable<getAllGatewaysForUser_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getAllGatewaysForUser_args");

    private static final org.apache.thrift.protocol.TField AUTHZ_TOKEN_FIELD_DESC = new org.apache.thrift.protocol.TField("authzToken", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField REQUESTER_USERNAME_FIELD_DESC = new org.apache.thrift.protocol.TField("requesterUsername", org.apache.thrift.protocol.TType.STRING, (short)2);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new getAllGatewaysForUser_argsStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new getAllGatewaysForUser_argsTupleSchemeFactory();

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public java.lang.String requesterUsername; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      AUTHZ_TOKEN((short)1, "authzToken"),
      REQUESTER_USERNAME((short)2, "requesterUsername");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // REQUESTER_USERNAME
            return REQUESTER_USERNAME;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.AUTHZ_TOKEN, new org.apache.thrift.meta_data.FieldMetaData("authzToken", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.security.AuthzToken.class)));
      tmpMap.put(_Fields.REQUESTER_USERNAME, new org.apache.thrift.meta_data.FieldMetaData("requesterUsername", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getAllGatewaysForUser_args.class, metaDataMap);
    }

    public getAllGatewaysForUser_args() {
    }

    public getAllGatewaysForUser_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      java.lang.String requesterUsername)
    {
      this();
      this.authzToken = authzToken;
      this.requesterUsername = requesterUsername;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getAllGatewaysForUser_args(getAllGatewaysForUser_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetRequesterUsername()) {
        this.requesterUsername = other.requesterUsername;
      }
    }

    public getAllGatewaysForUser_args deepCopy() {
      return new getAllGatewaysForUser_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.requesterUsername = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public getAllGatewaysForUser_args setAuthzToken(org.apache.airavata.model.security.AuthzToken authzToken) {
      this.authzToken = authzToken;
      return this;
    }

    public void unsetAuthzToken() {
      this.authzToken = null;
    }

    /** Returns true if field authzToken is set (has been assigned a value) and false otherwise */
    public boolean isSetAuthzToken() {
      return this.authzToken != null;
    }

    public void setAuthzTokenIsSet(boolean value) {
      if (!value) {
        this.authzToken = null;
      }
    }

    public java.lang.String getRequesterUsername() {
      return this.requesterUsername;
    }

    public getAllGatewaysForUser_args setRequesterUsername(java.lang.String requesterUsername) {
      this.requesterUsername = requesterUsername;
      return this;
    }

    public void unsetRequesterUsername() {
      this.requesterUsername = null;
    }

    /** Returns true if field requesterUsername is set (has been assigned a value) and false otherwise */
    public boolean isSetRequesterUsername() {
      return this.requesterUsername != null;
    }

    public void setRequesterUsernameIsSet(boolean value) {
      if (!value) {
        this.requesterUsername = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case AUTHZ_TOKEN:
        if (value == null) {
          unsetAuthzToken();
        } else {
          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
        }
        break;

      case REQUESTER_USERNAME:
        if (value == null) {
          unsetRequesterUsername();
        } else {
          setRequesterUsername((java.lang.String)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case REQUESTER_USERNAME:
        return getRequesterUsername();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case REQUESTER_USERNAME:
        return isSetRequesterUsername();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof getAllGatewaysForUser_args)
        return this.equals((getAllGatewaysForUser_args)that);
      return false;
    }

    public boolean equals(getAllGatewaysForUser_args that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_authzToken = true && this.isSetAuthzToken();
      boolean that_present_authzToken = true && that.isSetAuthzToken();
      if (this_present_authzToken || that_present_authzToken) {
        if (!(this_present_authzToken && that_present_authzToken))
          return false;
        if (!this.authzToken.equals(that.authzToken))
          return false;
      }

      boolean this_present_requesterUsername = true && this.isSetRequesterUsername();
      boolean that_present_requesterUsername = true && that.isSetRequesterUsername();
      if (this_present_requesterUsername || that_present_requesterUsername) {
        if (!(this_present_requesterUsername && that_present_requesterUsername))
          return false;
        if (!this.requesterUsername.equals(that.requesterUsername))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetAuthzToken()) ? 131071 : 524287);
      if (isSetAuthzToken())
        hashCode = hashCode * 8191 + authzToken.hashCode();

      hashCode = hashCode * 8191 + ((isSetRequesterUsername()) ? 131071 : 524287);
      if (isSetRequesterUsername())
        hashCode = hashCode * 8191 + requesterUsername.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(getAllGatewaysForUser_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetAuthzToken()).compareTo(other.isSetAuthzToken());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAuthzToken()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.authzToken, other.authzToken);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetRequesterUsername()).compareTo(other.isSetRequesterUsername());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetRequesterUsername()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.requesterUsername, other.requesterUsername);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("getAllGatewaysForUser_args(");
      boolean first = true;

      sb.append("authzToken:");
      if (this.authzToken == null) {
        sb.append("null");
      } else {
        sb.append(this.authzToken);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("requesterUsername:");
      if (this.requesterUsername == null) {
        sb.append("null");
      } else {
        sb.append(this.requesterUsername);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (authzToken == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'authzToken' was not present! Struct: " + toString());
      }
      if (requesterUsername == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'requesterUsername' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
      if (authzToken != null) {
        authzToken.validate();
      }
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class getAllGatewaysForUser_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getAllGatewaysForUser_argsStandardScheme getScheme() {
        return new getAllGatewaysForUser_argsStandardScheme();
      }
    }

    private static class getAllGatewaysForUser_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<getAllGatewaysForUser_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getAllGatewaysForUser_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TField schemeField;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // AUTHZ_TOKEN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
                struct.authzToken.read(iprot);
                struct.setAuthzTokenIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // REQUESTER_USERNAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.requesterUsername = iprot.readString();
                struct.setRequesterUsernameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getAllGatewaysForUser_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.authzToken != null) {
          oprot.writeFieldBegin(AUTHZ_TOKEN_FIELD_DESC);
          struct.authzToken.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.requesterUsername != null) {
          oprot.writeFieldBegin(REQUESTER_USERNAME_FIELD_DESC);
          oprot.writeString(struct.requesterUsername);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getAllGatewaysForUser_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getAllGatewaysForUser_argsTupleScheme getScheme() {
        return new getAllGatewaysForUser_argsTupleScheme();
      }
    }

    private static class getAllGatewaysForUser_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<getAllGatewaysForUser_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getAllGatewaysForUser_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.requesterUsername);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getAllGatewaysForUser_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
        struct.authzToken.read(iprot);
        struct.setAuthzTokenIsSet(true);
        struct.requesterUsername = iprot.readString();
        struct.setRequesterUsernameIsSet(true);
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class getAllGatewaysForUser_result implements org.apache.thrift.TBase<getAllGatewaysForUser_result, getAllGatewaysForUser_result._Fields>, java.io.Serializable, Cloneable, Comparable<getAllGatewaysForUser_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getAllGatewaysForUser_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.LIST, (short)0);
    private static final org.apache.thrift.protocol.TField TPE_FIELD_DESC = new org.apache.thrift.protocol.TField("tpe", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField AE_FIELD_DESC = new org.apache.thrift.protocol.TField("ae", org.apache.thrift.protocol.TType.STRUCT, (short)2);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new getAllGatewaysForUser_resultStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new getAllGatewaysForUser_resultTupleSchemeFactory();

    public java.util.List<org.apache.airavata.model.workspace.Gateway> success; // required
    public org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException tpe; // required
    public org.apache.airavata.model.error.AuthorizationException ae; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      TPE((short)1, "tpe"),
      AE((short)2, "ae");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // TPE
            return TPE;
          case 2: // AE
            return AE;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
              new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.workspace.Gateway.class))));
      tmpMap.put(_Fields.TPE, new org.apache.thrift.meta_data.FieldMetaData("tpe", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException.class)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.error.AuthorizationException.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getAllGatewaysForUser_result.class, metaDataMap);
    }

    public getAllGatewaysForUser_result() {
    }

    public getAllGatewaysForUser_result(
      java.util.List<org.apache.airavata.model.workspace.Gateway> success,
      org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException tpe,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      this.tpe = tpe;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getAllGatewaysForUser_result(getAllGatewaysForUser_result other) {
      if (other.isSetSuccess()) {
        java.util.List<org.apache.airavata.model.workspace.Gateway> __this__success = new java.util.ArrayList<org.apache.airavata.model.workspace.Gateway>(other.success.size());
        for (org.apache.airavata.model.workspace.Gateway other_element : other.success) {
          __this__success.add(new org.apache.airavata.model.workspace.Gateway(other_element));
        }
        this.success = __this__success;
      }
      if (other.isSetTpe()) {
        this.tpe = new org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException(other.tpe);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public getAllGatewaysForUser_result deepCopy() {
      return new getAllGatewaysForUser_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.tpe = null;
      this.ae = null;
    }

    public int getSuccessSize() {
      return (this.success == null) ? 0 : this.success.size();
    }

    public java.util.Iterator<org.apache.airavata.model.workspace.Gateway> getSuccessIterator() {
      return (this.success == null) ? null : this.success.iterator();
    }

    public void addToSuccess(org.apache.airavata.model.workspace.Gateway elem) {
      if (this.success == null) {
        this.success = new java.util.ArrayList<org.apache.airavata.model.workspace.Gateway>();
      }
      this.success.add(elem);
    }

    public java.util.List<org.apache.airavata.model.workspace.Gateway> getSuccess() {
      return this.success;
    }

    public getAllGatewaysForUser_result setSuccess(java.util.List<org.apache.airavata.model.workspace.Gateway> success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return this.success != null;
    }

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException getTpe() {
      return this.tpe;
    }

    public getAllGatewaysForUser_result setTpe(org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException tpe) {
      this.tpe = tpe;
      return this;
    }

    public void unsetTpe() {
      this.tpe = null;
    }

    /** Returns true if field tpe is set (has been assigned a value) and false otherwise */
    public boolean isSetTpe() {
      return this.tpe != null;
    }

    public void setTpeIsSet(boolean value) {
      if (!value) {
        this.tpe = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public getAllGatewaysForUser_result setAe(org.apache.airavata.model.error.AuthorizationException ae) {
      this.ae = ae;
      return this;
    }

    public void unsetAe() {
      this.ae = null;
    }

    /** Returns true if field ae is set (has been assigned a value) and false otherwise */
    public boolean isSetAe() {
      return this.ae != null;
    }

    public void setAeIsSet(boolean value) {
      if (!value) {
        this.ae = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.util.List<org.apache.airavata.model.workspace.Gateway>)value);
        }
        break;

      case TPE:
        if (value == null) {
          unsetTpe();
        } else {
          setTpe((org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case TPE:
        return getTpe();

      case AE:
        return getAe();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case TPE:
        return isSetTpe();
      case AE:
        return isSetAe();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof getAllGatewaysForUser_result)
        return this.equals((getAllGatewaysForUser_result)that);
      return false;
    }

    public boolean equals(getAllGatewaysForUser_result that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_tpe = true && this.isSetTpe();
      boolean that_present_tpe = true && that.isSetTpe();
      if (this_present_tpe || that_present_tpe) {
        if (!(this_present_tpe && that_present_tpe))
          return false;
        if (!this.tpe.equals(that.tpe))
          return false;
      }

      boolean this_present_ae = true && this.isSetAe();
      boolean that_present_ae = true && that.isSetAe();
      if (this_present_ae || that_present_ae) {
        if (!(this_present_ae && that_present_ae))
          return false;
        if (!this.ae.equals(that.ae))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
      if (isSetSuccess())
        hashCode = hashCode * 8191 + success.hashCode();

      hashCode = hashCode * 8191 + ((isSetTpe()) ? 131071 : 524287);
      if (isSetTpe())
        hashCode = hashCode * 8191 + tpe.hashCode();

      hashCode = hashCode * 8191 + ((isSetAe()) ? 131071 : 524287);
      if (isSetAe())
        hashCode = hashCode * 8191 + ae.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(getAllGatewaysForUser_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetTpe()).compareTo(other.isSetTpe());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetTpe()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.tpe, other.tpe);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetAe()).compareTo(other.isSetAe());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAe()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ae, other.ae);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("getAllGatewaysForUser_result(");
      boolean first = true;

      sb.append("success:");
      if (this.success == null) {
        sb.append("null");
      } else {
        sb.append(this.success);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("tpe:");
      if (this.tpe == null) {
        sb.append("null");
      } else {
        sb.append(this.tpe);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ae:");
      if (this.ae == null) {
        sb.append("null");
      } else {
        sb.append(this.ae);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class getAllGatewaysForUser_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getAllGatewaysForUser_resultStandardScheme getScheme() {
        return new getAllGatewaysForUser_resultStandardScheme();
      }
    }

    private static class getAllGatewaysForUser_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<getAllGatewaysForUser_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getAllGatewaysForUser_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TField schemeField;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
                {
                  org.apache.thrift.protocol.TList _list8 = iprot.readListBegin();
                  struct.success = new java.util.ArrayList<org.apache.airavata.model.workspace.Gateway>(_list8.size);
                  org.apache.airavata.model.workspace.Gateway _elem9;
                  for (int _i10 = 0; _i10 < _list8.size; ++_i10)
                  {
                    _elem9 = new org.apache.airavata.model.workspace.Gateway();
                    _elem9.read(iprot);
                    struct.success.add(_elem9);
                  }
                  iprot.readListEnd();
                }
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // TPE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.tpe = new org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException();
                struct.tpe.read(iprot);
                struct.setTpeIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // AE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ae = new org.apache.airavata.model.error.AuthorizationException();
                struct.ae.read(iprot);
                struct.setAeIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getAllGatewaysForUser_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, struct.success.size()));
            for (org.apache.airavata.model.workspace.Gateway _iter11 : struct.success)
            {
              _iter11.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.tpe != null) {
          oprot.writeFieldBegin(TPE_FIELD_DESC);
          struct.tpe.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ae != null) {
          oprot.writeFieldBegin(AE_FIELD_DESC);
          struct.ae.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getAllGatewaysForUser_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getAllGatewaysForUser_resultTupleScheme getScheme() {
        return new getAllGatewaysForUser_resultTupleScheme();
      }
    }

    private static class getAllGatewaysForUser_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<getAllGatewaysForUser_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getAllGatewaysForUser_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet optionals = new java.util.BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetTpe()) {
          optionals.set(1);
        }
        if (struct.isSetAe()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetSuccess()) {
          {
            oprot.writeI32(struct.success.size());
            for (org.apache.airavata.model.workspace.Gateway _iter12 : struct.success)
            {
              _iter12.write(oprot);
            }
          }
        }
        if (struct.isSetTpe()) {
          struct.tpe.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getAllGatewaysForUser_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet incoming = iprot.readBitSet(3);
        if (incoming.get(0)) {
          {
            org.apache.thrift.protocol.TList _list13 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
            struct.success = new java.util.ArrayList<org.apache.airavata.model.workspace.Gateway>(_list13.size);
            org.apache.airavata.model.workspace.Gateway _elem14;
            for (int _i15 = 0; _i15 < _list13.size; ++_i15)
            {
              _elem14 = new org.apache.airavata.model.workspace.Gateway();
              _elem14.read(iprot);
              struct.success.add(_elem14);
            }
          }
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.tpe = new org.apache.airavata.service.profile.tenant.cpi.exception.TenantProfileServiceException();
          struct.tpe.read(iprot);
          struct.setTpeIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

}
